@quicknode/sdk 3.0.0-alpha.6 → 3.1.0-alpha.15
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 +96 -3434
- package/errors.js +7 -7
- package/index.d.ts +47 -181
- package/index.darwin-arm64.node +0 -0
- package/index.js +2 -2
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-arm64-musl.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.linux-x64-musl.node +0 -0
- package/package.json +7 -6
- package/sdk.d.ts +77 -42
- package/sdk.js +20 -34
- package/sdk.mjs +2 -2
package/README.md
CHANGED
|
@@ -1,3375 +1,60 @@
|
|
|
1
1
|
# Quicknode SDK
|
|
2
2
|
|
|
3
|
-
A unified SDK for building on
|
|
3
|
+
A unified SDK for building on Quicknode.
|
|
4
4
|
|
|
5
5
|
Rust SDK with Python, Node.js, and Ruby bindings.
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
|
+
- [Per-language docs](#per-language-docs)
|
|
9
10
|
- [Project Structure](#project-structure)
|
|
10
11
|
- [Installation](#installation)
|
|
11
|
-
- [Quick Start](#quick-start)
|
|
12
|
-
- [Configuration](#configuration)
|
|
13
|
-
- [Option A — Pass config directly](#option-a--pass-config-directly)
|
|
14
|
-
- [Option B — Load from environment (`from_env()`)](#option-b--load-from-environment-from_env)
|
|
15
|
-
- [API Reference](#api-reference)
|
|
16
|
-
- [Language conventions](#language-conventions)
|
|
17
|
-
- [Admin Client](#admin-client)
|
|
18
|
-
- [Endpoints](#endpoints)
|
|
19
|
-
- [Endpoint Tags](#endpoint-tags)
|
|
20
|
-
- [Teams](#teams)
|
|
21
|
-
- [Usage](#usage)
|
|
22
|
-
- [Logs](#logs)
|
|
23
|
-
- [Endpoint Security](#endpoint-security)
|
|
24
|
-
- [Security Options](#security-options)
|
|
25
|
-
- [Tokens](#tokens)
|
|
26
|
-
- [Referrers](#referrers)
|
|
27
|
-
- [IPs](#ips)
|
|
28
|
-
- [Domain Masks](#domain-masks)
|
|
29
|
-
- [JWTs](#jwts)
|
|
30
|
-
- [Request Filters](#request-filters)
|
|
31
|
-
- [Multichain](#multichain)
|
|
32
|
-
- [IP Custom Headers](#ip-custom-headers)
|
|
33
|
-
- [Method Rate Limits](#method-rate-limits)
|
|
34
|
-
- [Endpoint Rate Limits](#endpoint-rate-limits)
|
|
35
|
-
- [Metrics](#metrics)
|
|
36
|
-
- [Chains](#chains)
|
|
37
|
-
- [Billing](#billing)
|
|
38
|
-
- [Bulk Operations](#bulk-operations)
|
|
39
|
-
- [Account Tags](#account-tags)
|
|
40
|
-
- [Streams Client](#streams-client)
|
|
41
|
-
- [Datasets, Regions, and Destinations](#datasets-regions-and-destinations)
|
|
42
|
-
- [Streams methods](#streams-methods)
|
|
43
|
-
- [Webhooks Client](#webhooks-client)
|
|
44
|
-
- [Templates and destination](#templates-and-destination)
|
|
45
|
-
- [Webhooks methods](#webhooks-methods)
|
|
46
|
-
- [KV Store Client](#kv-store-client)
|
|
47
|
-
- [Sets](#sets)
|
|
48
|
-
- [Lists](#lists)
|
|
49
|
-
- [Error Handling](#error-handling)
|
|
50
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)
|
|
51
22
|
- [License](#license)
|
|
52
23
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
sdk/
|
|
57
|
-
├── crates/
|
|
58
|
-
│ ├── core/ # Pure Rust business logic
|
|
59
|
-
│ ├── python/ # PyO3 bindings
|
|
60
|
-
│ ├── node/ # napi-rs bindings
|
|
61
|
-
│ └── ruby/ # magnus bindings
|
|
62
|
-
├── python/sdk/ # Python package with type hints
|
|
63
|
-
├── npm/ # Node.js package with TypeScript types
|
|
64
|
-
├── ruby/ # Ruby package
|
|
65
|
-
└── pyproject.toml # maturin build config
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Installation
|
|
69
|
-
|
|
70
|
-
**Python:** `uv add quicknode-sdk`
|
|
71
|
-
|
|
72
|
-
**Node.js:** `npm install quicknode-sdk`
|
|
73
|
-
|
|
74
|
-
**Ruby:** `gem install quicknode-sdk` _(not yet published — see Development below)_
|
|
75
|
-
|
|
76
|
-
## Quick Start
|
|
77
|
-
|
|
78
|
-
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.
|
|
79
|
-
|
|
80
|
-
```rust
|
|
81
|
-
// Rust
|
|
82
|
-
use quicknode_sdk::{QuickNodeSdk, SdkFullConfig};
|
|
83
|
-
|
|
84
|
-
#[tokio::main]
|
|
85
|
-
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
86
|
-
let qn = QuickNodeSdk::from_env()?;
|
|
87
|
-
let resp = qn.admin.get_endpoints(&Default::default()).await?;
|
|
88
|
-
println!("{} endpoints", resp.data.len());
|
|
89
|
-
Ok(())
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
```python
|
|
94
|
-
# Python
|
|
95
|
-
import asyncio
|
|
96
|
-
from sdk import QuickNodeSdk
|
|
97
|
-
|
|
98
|
-
async def main():
|
|
99
|
-
qn = QuickNodeSdk.from_env()
|
|
100
|
-
resp = await qn.admin.get_endpoints()
|
|
101
|
-
print(f"{len(resp.data)} endpoints")
|
|
102
|
-
|
|
103
|
-
asyncio.run(main())
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
// Node.js
|
|
108
|
-
import { QuickNodeSdk } from "quicknode-sdk";
|
|
109
|
-
|
|
110
|
-
const qn = QuickNodeSdk.fromEnv();
|
|
111
|
-
const resp = await qn.admin.getEndpoints();
|
|
112
|
-
console.log(`${resp.data.length} endpoints`);
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
```ruby
|
|
116
|
-
# Ruby
|
|
117
|
-
require "json"
|
|
118
|
-
require "quicknode_sdk"
|
|
119
|
-
|
|
120
|
-
qn = QuickNodeSdk::SDK.from_env
|
|
121
|
-
resp = JSON.parse(qn.admin.get_endpoints({}))
|
|
122
|
-
puts "#{resp["data"].length} endpoints"
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## Configuration
|
|
126
|
-
|
|
127
|
-
There are two ways to configure the SDK.
|
|
128
|
-
|
|
129
|
-
### Option A — Pass config directly
|
|
130
|
-
|
|
131
|
-
```python
|
|
132
|
-
# Python
|
|
133
|
-
from sdk import QuickNodeSdk, SdkFullConfig, HttpConfig
|
|
134
|
-
qn = QuickNodeSdk(SdkFullConfig(api_key="your-key", http=HttpConfig(timeout_secs=30)))
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
// Node.js
|
|
139
|
-
import { QuickNodeSdk } from "quicknode-sdk";
|
|
140
|
-
const qn = new QuickNodeSdk({ apiKey: "your-key", http: { timeoutSecs: 30 } });
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
```rust
|
|
144
|
-
// Rust
|
|
145
|
-
let qn = QuickNodeSdk::new(&SdkFullConfig::builder().api_key("your-key").build())?;
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Option B — Load from environment (`from_env()`)
|
|
149
|
-
|
|
150
|
-
```python
|
|
151
|
-
# Python
|
|
152
|
-
qn = QuickNodeSdk.from_env()
|
|
153
|
-
```
|
|
154
|
-
```typescript
|
|
155
|
-
// Node.js
|
|
156
|
-
const qn = QuickNodeSdk.fromEnv();
|
|
157
|
-
```
|
|
158
|
-
```ruby
|
|
159
|
-
# Ruby
|
|
160
|
-
qn = QuickNodeSdk::SDK.from_env
|
|
161
|
-
```
|
|
162
|
-
```rust
|
|
163
|
-
// Rust
|
|
164
|
-
let qn = QuickNodeSdk::from_env()?;
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Environment variables (prefix `QN_SDK__`, separator `__`):
|
|
168
|
-
|
|
169
|
-
| Variable | Required | Default | Description |
|
|
170
|
-
|----------|----------|---------|-------------|
|
|
171
|
-
| `QN_SDK__API_KEY` | yes | — | Your QuickNode API key |
|
|
172
|
-
| `QN_SDK__HTTP__TIMEOUT_SECS` | no | 30 | HTTP request timeout in seconds |
|
|
173
|
-
| `QN_SDK__HTTP__POOL_MAX_IDLE_PER_HOST` | no | — | Max idle HTTP connections per host |
|
|
174
|
-
| `QN_SDK__ADMIN__BASE_URL` | no | `https://api.quicknode.com/v0/` | Override admin API base URL (HTTPS, must end with `/`) |
|
|
175
|
-
| `QN_SDK__STREAMS__BASE_URL` | no | `https://api.quicknode.com/streams/rest/v1/` | Override streams base URL |
|
|
176
|
-
| `QN_SDK__WEBHOOKS__BASE_URL` | no | `https://api.quicknode.com/webhooks/rest/v1/` | Override webhooks base URL |
|
|
177
|
-
| `QN_SDK__KVSTORE__BASE_URL` | no | `https://api.quicknode.com/kv/rest/v1/` | Override KV store base URL |
|
|
178
|
-
|
|
179
|
-
## API Reference
|
|
180
|
-
|
|
181
|
-
Each method below shows the call pattern in Rust, Python, Node.js, and Ruby in that order. Snippets assume `qn` was already constructed via the Quick Start. Optional parameters are skipped unless showing one is needed to illustrate usage.
|
|
182
|
-
|
|
183
|
-
### Language conventions
|
|
184
|
-
|
|
185
|
-
- **Rust**: methods are `async` and return `Result<T, SdkError>`. Request structs use the [`bon`](https://docs.rs/bon) builder pattern via `::builder()`.
|
|
186
|
-
- **Python**: methods are `async` — call with `await`. Parameters are kwargs; responses are native `pyclass` objects with attribute access.
|
|
187
|
-
- **Node.js**: methods are `async` and take a single options object with camelCase keys.
|
|
188
|
-
- **Ruby**: methods are **blocking** (not async). Parameters are a single Hash with symbol keys. Responses that carry data are returned as **JSON strings** — wrap calls with `JSON.parse`. Unknown keys raise `ArgumentError`.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
### Admin Client
|
|
193
|
-
|
|
194
|
-
Accessed as `qn.admin`. Manages endpoints, tags, teams, billing, usage, metrics, security, and rate limits. Backed by `https://api.quicknode.com/v0/`.
|
|
195
|
-
|
|
196
|
-
#### Endpoints
|
|
197
|
-
|
|
198
|
-
##### `get_endpoints` / `getEndpoints`
|
|
199
|
-
|
|
200
|
-
Returns a paginated list of endpoints on the account with optional search, filters (networks, statuses, labels, tags, dedicated, flat-rate), sorting, and pagination.
|
|
201
|
-
|
|
202
|
-
**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[]).
|
|
203
|
-
|
|
204
|
-
**Returns**: `GetEndpointsResponse` — `{ data: Endpoint[], pagination?: Pagination }`.
|
|
205
|
-
|
|
206
|
-
```rust
|
|
207
|
-
// Rust
|
|
208
|
-
let params = GetEndpointsRequest::builder()
|
|
209
|
-
.limit(20)
|
|
210
|
-
.sort_by("created_at".to_string())
|
|
211
|
-
.sort_direction("desc".to_string())
|
|
212
|
-
.build();
|
|
213
|
-
let resp = qn.admin.get_endpoints(¶ms).await?;
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
```python
|
|
217
|
-
# Python
|
|
218
|
-
resp = await qn.admin.get_endpoints(limit=20, sort_by="created_at", sort_direction="desc")
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
// Node.js
|
|
223
|
-
const resp = await qn.admin.getEndpoints({
|
|
224
|
-
limit: 20,
|
|
225
|
-
sortBy: "created_at",
|
|
226
|
-
sortDirection: "desc",
|
|
227
|
-
});
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
```ruby
|
|
231
|
-
# Ruby
|
|
232
|
-
resp = JSON.parse(qn.admin.get_endpoints(limit: 20, sort_by: "created_at", sort_direction: "desc"))
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
##### `create_endpoint` / `createEndpoint`
|
|
236
|
-
|
|
237
|
-
Creates a new endpoint for the given blockchain and network.
|
|
238
|
-
|
|
239
|
-
**Parameters**: `chain` (string, optional), `network` (string, optional).
|
|
240
|
-
|
|
241
|
-
**Returns**: `CreateEndpointResponse` with `data: SingleEndpoint`.
|
|
242
|
-
|
|
243
|
-
```rust
|
|
244
|
-
// Rust
|
|
245
|
-
let params = CreateEndpointRequest::builder()
|
|
246
|
-
.chain("ethereum".to_string())
|
|
247
|
-
.network("mainnet".to_string())
|
|
248
|
-
.build();
|
|
249
|
-
let resp = qn.admin.create_endpoint(¶ms).await?;
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
```python
|
|
253
|
-
# Python
|
|
254
|
-
resp = await qn.admin.create_endpoint(chain="ethereum", network="mainnet")
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
// Node.js
|
|
259
|
-
const resp = await qn.admin.createEndpoint({ chain: "ethereum", network: "mainnet" });
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
```ruby
|
|
263
|
-
# Ruby
|
|
264
|
-
resp = JSON.parse(qn.admin.create_endpoint(chain: "ethereum", network: "mainnet"))
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
##### `show_endpoint` / `showEndpoint`
|
|
268
|
-
|
|
269
|
-
Fetches a single endpoint by id, including its full security configuration and rate limits.
|
|
270
|
-
|
|
271
|
-
**Parameters**: `id` (string, required).
|
|
272
|
-
|
|
273
|
-
**Returns**: `ShowEndpointResponse` with `data: SingleEndpoint`.
|
|
274
|
-
|
|
275
|
-
```rust
|
|
276
|
-
// Rust
|
|
277
|
-
let resp = qn.admin.show_endpoint("ep-123").await?;
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
```python
|
|
281
|
-
# Python
|
|
282
|
-
resp = await qn.admin.show_endpoint("ep-123")
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
// Node.js
|
|
287
|
-
const resp = await qn.admin.showEndpoint("ep-123");
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
```ruby
|
|
291
|
-
# Ruby
|
|
292
|
-
resp = JSON.parse(qn.admin.show_endpoint(id: "ep-123"))
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
##### `update_endpoint` / `updateEndpoint`
|
|
296
|
-
|
|
297
|
-
Updates editable fields on an endpoint. Currently supports `label`.
|
|
298
|
-
|
|
299
|
-
**Parameters**: `id` (string, required); body: `label` (string, optional).
|
|
300
|
-
|
|
301
|
-
**Returns**: nothing.
|
|
302
|
-
|
|
303
|
-
```rust
|
|
304
|
-
// Rust
|
|
305
|
-
let params = UpdateEndpointRequest::builder().label("my label".to_string()).build();
|
|
306
|
-
qn.admin.update_endpoint("ep-123", ¶ms).await?;
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
```python
|
|
310
|
-
# Python
|
|
311
|
-
await qn.admin.update_endpoint("ep-123", label="my label")
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
```typescript
|
|
315
|
-
// Node.js
|
|
316
|
-
await qn.admin.updateEndpoint("ep-123", { label: "my label" });
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
```ruby
|
|
320
|
-
# Ruby
|
|
321
|
-
qn.admin.update_endpoint(id: "ep-123", label: "my label")
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
##### `archive_endpoint` / `archiveEndpoint`
|
|
325
|
-
|
|
326
|
-
Archives an endpoint. The HTTP verb is `DELETE` but the effect is archival, not permanent deletion.
|
|
327
|
-
|
|
328
|
-
**Parameters**: `id` (string, required).
|
|
329
|
-
|
|
330
|
-
**Returns**: nothing.
|
|
331
|
-
|
|
332
|
-
```rust
|
|
333
|
-
// Rust
|
|
334
|
-
qn.admin.archive_endpoint("ep-123").await?;
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
```python
|
|
338
|
-
# Python
|
|
339
|
-
await qn.admin.archive_endpoint("ep-123")
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
```typescript
|
|
343
|
-
// Node.js
|
|
344
|
-
await qn.admin.archiveEndpoint("ep-123");
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
```ruby
|
|
348
|
-
# Ruby
|
|
349
|
-
qn.admin.archive_endpoint(id: "ep-123")
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
##### `update_endpoint_status` / `updateEndpointStatus`
|
|
353
|
-
|
|
354
|
-
Pauses or unpauses an endpoint.
|
|
355
|
-
|
|
356
|
-
**Parameters**: `id` (string, required); body: `status` (string, required — `"active"` or `"paused"`).
|
|
357
|
-
|
|
358
|
-
**Returns**: `UpdateEndpointStatusResponse`.
|
|
359
|
-
|
|
360
|
-
```rust
|
|
361
|
-
// Rust
|
|
362
|
-
let params = UpdateEndpointStatusRequest::builder().status("paused".to_string()).build();
|
|
363
|
-
qn.admin.update_endpoint_status("ep-123", ¶ms).await?;
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
```python
|
|
367
|
-
# Python
|
|
368
|
-
await qn.admin.update_endpoint_status("ep-123", status="paused")
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
// Node.js
|
|
373
|
-
await qn.admin.updateEndpointStatus("ep-123", { status: "paused" });
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
```ruby
|
|
377
|
-
# Ruby
|
|
378
|
-
JSON.parse(qn.admin.update_endpoint_status(id: "ep-123", status: "paused"))
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
#### Endpoint Tags
|
|
382
|
-
|
|
383
|
-
Per-endpoint tag add/remove. For account-wide tag management see [Account Tags](#account-tags).
|
|
384
|
-
|
|
385
|
-
##### `create_tag` / `createTag`
|
|
386
|
-
|
|
387
|
-
Tags an endpoint with the given label. Creates the tag on the account if it does not exist.
|
|
388
|
-
|
|
389
|
-
**Parameters**: `id` (string, required); body: `label` (string, optional).
|
|
390
|
-
|
|
391
|
-
**Returns**: nothing.
|
|
392
|
-
|
|
393
|
-
```rust
|
|
394
|
-
// Rust
|
|
395
|
-
let params = CreateTagRequest::builder().label("prod".to_string()).build();
|
|
396
|
-
qn.admin.create_tag("ep-123", ¶ms).await?;
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
```python
|
|
400
|
-
# Python
|
|
401
|
-
await qn.admin.create_tag("ep-123", label="prod")
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
// Node.js
|
|
406
|
-
await qn.admin.createTag("ep-123", { label: "prod" });
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
```ruby
|
|
410
|
-
# Ruby
|
|
411
|
-
qn.admin.create_tag(id: "ep-123", label: "prod")
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
##### `delete_tag` / `deleteTag`
|
|
415
|
-
|
|
416
|
-
Removes a tag from a specific endpoint.
|
|
417
|
-
|
|
418
|
-
**Parameters**: `id` (endpoint id, string, required), `tag_id` (string, required).
|
|
419
|
-
|
|
420
|
-
**Returns**: nothing.
|
|
421
|
-
|
|
422
|
-
```rust
|
|
423
|
-
// Rust
|
|
424
|
-
qn.admin.delete_tag("ep-123", "42").await?;
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
```python
|
|
428
|
-
# Python
|
|
429
|
-
await qn.admin.delete_tag("ep-123", "42")
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
```typescript
|
|
433
|
-
// Node.js
|
|
434
|
-
await qn.admin.deleteTag("ep-123", "42");
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
```ruby
|
|
438
|
-
# Ruby
|
|
439
|
-
qn.admin.delete_tag(id: "ep-123", tag_id: "42")
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
#### Teams
|
|
443
|
-
|
|
444
|
-
##### `list_teams` / `listTeams`
|
|
445
|
-
|
|
446
|
-
Lists all teams on the account.
|
|
447
|
-
|
|
448
|
-
**Parameters**: none.
|
|
449
|
-
|
|
450
|
-
**Returns**: `ListTeamsResponse` with `data: TeamSummary[]`.
|
|
451
|
-
|
|
452
|
-
```rust
|
|
453
|
-
// Rust
|
|
454
|
-
let resp = qn.admin.list_teams().await?;
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
```python
|
|
458
|
-
# Python
|
|
459
|
-
resp = await qn.admin.list_teams()
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
```typescript
|
|
463
|
-
// Node.js
|
|
464
|
-
const resp = await qn.admin.listTeams();
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
```ruby
|
|
468
|
-
# Ruby
|
|
469
|
-
resp = JSON.parse(qn.admin.list_teams)
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
##### `create_team` / `createTeam`
|
|
473
|
-
|
|
474
|
-
Creates a new team.
|
|
475
|
-
|
|
476
|
-
**Parameters**: `name` (string, required).
|
|
477
|
-
|
|
478
|
-
**Returns**: `CreateTeamResponse` with `data: CreateTeamData`.
|
|
479
|
-
|
|
480
|
-
```rust
|
|
481
|
-
// Rust
|
|
482
|
-
let params = CreateTeamRequest::builder().name("Payments".to_string()).build();
|
|
483
|
-
let resp = qn.admin.create_team(¶ms).await?;
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
```python
|
|
487
|
-
# Python
|
|
488
|
-
resp = await qn.admin.create_team(name="Payments")
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
```typescript
|
|
492
|
-
// Node.js
|
|
493
|
-
const resp = await qn.admin.createTeam({ name: "Payments" });
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
```ruby
|
|
497
|
-
# Ruby
|
|
498
|
-
resp = JSON.parse(qn.admin.create_team(name: "Payments"))
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
##### `get_team` / `getTeam`
|
|
502
|
-
|
|
503
|
-
Fetches team detail including pending invites.
|
|
504
|
-
|
|
505
|
-
**Parameters**: `id` (i64, required).
|
|
506
|
-
|
|
507
|
-
**Returns**: `GetTeamResponse` with `data: TeamDetail`.
|
|
508
|
-
|
|
509
|
-
```rust
|
|
510
|
-
// Rust
|
|
511
|
-
let resp = qn.admin.get_team(42).await?;
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
```python
|
|
515
|
-
# Python
|
|
516
|
-
resp = await qn.admin.get_team(42)
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
```typescript
|
|
520
|
-
// Node.js
|
|
521
|
-
const resp = await qn.admin.getTeam(42);
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
```ruby
|
|
525
|
-
# Ruby
|
|
526
|
-
resp = JSON.parse(qn.admin.get_team(id: 42))
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
##### `delete_team` / `deleteTeam`
|
|
530
|
-
|
|
531
|
-
Deletes a team.
|
|
532
|
-
|
|
533
|
-
**Parameters**: `id` (i64, required).
|
|
534
|
-
|
|
535
|
-
**Returns**: `DeleteTeamResponse`.
|
|
536
|
-
|
|
537
|
-
```rust
|
|
538
|
-
// Rust
|
|
539
|
-
qn.admin.delete_team(42).await?;
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
```python
|
|
543
|
-
# Python
|
|
544
|
-
await qn.admin.delete_team(42)
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
```typescript
|
|
548
|
-
// Node.js
|
|
549
|
-
await qn.admin.deleteTeam(42);
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
```ruby
|
|
553
|
-
# Ruby
|
|
554
|
-
qn.admin.delete_team(id: 42)
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
##### `list_team_endpoints` / `listTeamEndpoints`
|
|
558
|
-
|
|
559
|
-
Lists endpoints accessible to a team.
|
|
560
|
-
|
|
561
|
-
**Parameters**: `id` (i64, required).
|
|
562
|
-
|
|
563
|
-
**Returns**: `ListTeamEndpointsResponse` with `data: TeamEndpoint[]`.
|
|
564
|
-
|
|
565
|
-
```rust
|
|
566
|
-
// Rust
|
|
567
|
-
let resp = qn.admin.list_team_endpoints(42).await?;
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
```python
|
|
571
|
-
# Python
|
|
572
|
-
resp = await qn.admin.list_team_endpoints(42)
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
```typescript
|
|
576
|
-
// Node.js
|
|
577
|
-
const resp = await qn.admin.listTeamEndpoints(42);
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
```ruby
|
|
581
|
-
# Ruby
|
|
582
|
-
resp = JSON.parse(qn.admin.list_team_endpoints(id: 42))
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
##### `update_team_endpoints` / `updateTeamEndpoints`
|
|
586
|
-
|
|
587
|
-
Replaces the set of endpoints associated with a team. Pass an empty array to remove all.
|
|
588
|
-
|
|
589
|
-
**Parameters**: `id` (i64, required); body: `endpoint_ids` (string[], required).
|
|
590
|
-
|
|
591
|
-
**Returns**: `UpdateTeamEndpointsResponse`.
|
|
592
|
-
|
|
593
|
-
```rust
|
|
594
|
-
// Rust
|
|
595
|
-
let params = UpdateTeamEndpointsRequest::builder()
|
|
596
|
-
.endpoint_ids(vec!["ep-123".to_string(), "ep-456".to_string()])
|
|
597
|
-
.build();
|
|
598
|
-
qn.admin.update_team_endpoints(42, ¶ms).await?;
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
```python
|
|
602
|
-
# Python
|
|
603
|
-
await qn.admin.update_team_endpoints(42, endpoint_ids=["ep-123", "ep-456"])
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
```typescript
|
|
607
|
-
// Node.js
|
|
608
|
-
await qn.admin.updateTeamEndpoints(42, { endpointIds: ["ep-123", "ep-456"] });
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
```ruby
|
|
612
|
-
# Ruby
|
|
613
|
-
qn.admin.update_team_endpoints(id: 42, endpoint_ids: ["ep-123", "ep-456"])
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
##### `invite_team_member` / `inviteTeamMember`
|
|
617
|
-
|
|
618
|
-
Invites a user to a team. Existing users only need `email`; new users require `full_name` and `role`.
|
|
619
|
-
|
|
620
|
-
**Parameters**: `id` (i64, required); body: `email` (string, required), `full_name` (string, optional), `role` (string, optional — `admin` | `viewer` | `billing`).
|
|
621
|
-
|
|
622
|
-
**Returns**: `InviteTeamMemberResponse`.
|
|
623
|
-
|
|
624
|
-
```rust
|
|
625
|
-
// Rust
|
|
626
|
-
let params = InviteTeamMemberRequest::builder()
|
|
627
|
-
.email("alice@example.com".to_string())
|
|
628
|
-
.role("viewer".to_string())
|
|
629
|
-
.build();
|
|
630
|
-
qn.admin.invite_team_member(42, ¶ms).await?;
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
```python
|
|
634
|
-
# Python
|
|
635
|
-
await qn.admin.invite_team_member(42, email="alice@example.com", role="viewer")
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
```typescript
|
|
639
|
-
// Node.js
|
|
640
|
-
await qn.admin.inviteTeamMember(42, { email: "alice@example.com", role: "viewer" });
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
```ruby
|
|
644
|
-
# Ruby
|
|
645
|
-
qn.admin.invite_team_member(id: 42, email: "alice@example.com", role: "viewer")
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
##### `remove_team_member` / `removeTeamMember`
|
|
649
|
-
|
|
650
|
-
Removes a user from a team.
|
|
651
|
-
|
|
652
|
-
**Parameters**: `id` (team id, i64, required), `user_id` (i64, required).
|
|
653
|
-
|
|
654
|
-
**Returns**: `RemoveTeamMemberResponse`.
|
|
655
|
-
|
|
656
|
-
```rust
|
|
657
|
-
// Rust
|
|
658
|
-
qn.admin.remove_team_member(42, 7).await?;
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
```python
|
|
662
|
-
# Python
|
|
663
|
-
await qn.admin.remove_team_member(42, 7)
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
```typescript
|
|
667
|
-
// Node.js
|
|
668
|
-
await qn.admin.removeTeamMember(42, 7);
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
```ruby
|
|
672
|
-
# Ruby
|
|
673
|
-
qn.admin.remove_team_member(id: 42, user_id: 7)
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
##### `resend_team_invite` / `resendTeamInvite`
|
|
677
|
-
|
|
678
|
-
Re-sends a pending team invitation.
|
|
679
|
-
|
|
680
|
-
**Parameters**: `id` (team id, i64, required), `user_id` (i64, required).
|
|
681
|
-
|
|
682
|
-
**Returns**: `ResendTeamInviteResponse`.
|
|
683
|
-
|
|
684
|
-
```rust
|
|
685
|
-
// Rust
|
|
686
|
-
qn.admin.resend_team_invite(42, 7).await?;
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
```python
|
|
690
|
-
# Python
|
|
691
|
-
await qn.admin.resend_team_invite(42, 7)
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
```typescript
|
|
695
|
-
// Node.js
|
|
696
|
-
await qn.admin.resendTeamInvite(42, 7);
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
```ruby
|
|
700
|
-
# Ruby
|
|
701
|
-
qn.admin.resend_team_invite(id: 42, user_id: 7)
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
#### Usage
|
|
705
|
-
|
|
706
|
-
All usage methods accept optional `start_time` and `end_time` Unix timestamps. Omit both for account-to-date totals.
|
|
707
|
-
|
|
708
|
-
##### `get_usage` / `getUsage`
|
|
709
|
-
|
|
710
|
-
Aggregate account usage for a time window.
|
|
711
|
-
|
|
712
|
-
**Returns**: `GetUsageResponse` with `data: UsageData` (`credits_used`, `credits_remaining`, `limit`, `overages`, `start_time`, `end_time`).
|
|
713
|
-
|
|
714
|
-
```rust
|
|
715
|
-
// Rust
|
|
716
|
-
let resp = qn.admin.get_usage(&GetUsageRequest::default()).await?;
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
```python
|
|
720
|
-
# Python
|
|
721
|
-
resp = await qn.admin.get_usage()
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
```typescript
|
|
725
|
-
// Node.js
|
|
726
|
-
const resp = await qn.admin.getUsage();
|
|
727
|
-
```
|
|
728
|
-
|
|
729
|
-
```ruby
|
|
730
|
-
# Ruby
|
|
731
|
-
resp = JSON.parse(qn.admin.get_usage({}))
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
##### `get_usage_by_endpoint` / `getUsageByEndpoint`
|
|
735
|
-
|
|
736
|
-
Per-endpoint usage breakdown.
|
|
737
|
-
|
|
738
|
-
**Returns**: `GetUsageByEndpointResponse` with `data.endpoints: EndpointUsage[]`.
|
|
739
|
-
|
|
740
|
-
```rust
|
|
741
|
-
// Rust
|
|
742
|
-
let resp = qn.admin.get_usage_by_endpoint(&GetUsageRequest::default()).await?;
|
|
743
|
-
```
|
|
744
|
-
|
|
745
|
-
```python
|
|
746
|
-
# Python
|
|
747
|
-
resp = await qn.admin.get_usage_by_endpoint()
|
|
748
|
-
```
|
|
749
|
-
|
|
750
|
-
```typescript
|
|
751
|
-
// Node.js
|
|
752
|
-
const resp = await qn.admin.getUsageByEndpoint();
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
```ruby
|
|
756
|
-
# Ruby
|
|
757
|
-
resp = JSON.parse(qn.admin.get_usage_by_endpoint({}))
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
##### `get_usage_by_method` / `getUsageByMethod`
|
|
761
|
-
|
|
762
|
-
Per-RPC-method usage breakdown.
|
|
763
|
-
|
|
764
|
-
**Returns**: `GetUsageByMethodResponse` with `data.methods: MethodUsage[]`.
|
|
765
|
-
|
|
766
|
-
```rust
|
|
767
|
-
// Rust
|
|
768
|
-
let resp = qn.admin.get_usage_by_method(&GetUsageRequest::default()).await?;
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
```python
|
|
772
|
-
# Python
|
|
773
|
-
resp = await qn.admin.get_usage_by_method()
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
```typescript
|
|
777
|
-
// Node.js
|
|
778
|
-
const resp = await qn.admin.getUsageByMethod();
|
|
779
|
-
```
|
|
780
|
-
|
|
781
|
-
```ruby
|
|
782
|
-
# Ruby
|
|
783
|
-
resp = JSON.parse(qn.admin.get_usage_by_method({}))
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
##### `get_usage_by_chain` / `getUsageByChain`
|
|
787
|
-
|
|
788
|
-
Per-chain usage breakdown.
|
|
789
|
-
|
|
790
|
-
**Returns**: `GetUsageByChainResponse` with `data.chains: ChainUsage[]`.
|
|
791
|
-
|
|
792
|
-
```rust
|
|
793
|
-
// Rust
|
|
794
|
-
let resp = qn.admin.get_usage_by_chain(&GetUsageRequest::default()).await?;
|
|
795
|
-
```
|
|
796
|
-
|
|
797
|
-
```python
|
|
798
|
-
# Python
|
|
799
|
-
resp = await qn.admin.get_usage_by_chain()
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
```typescript
|
|
803
|
-
// Node.js
|
|
804
|
-
const resp = await qn.admin.getUsageByChain();
|
|
805
|
-
```
|
|
806
|
-
|
|
807
|
-
```ruby
|
|
808
|
-
# Ruby
|
|
809
|
-
resp = JSON.parse(qn.admin.get_usage_by_chain({}))
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
##### `get_usage_by_tag` / `getUsageByTag`
|
|
813
|
-
|
|
814
|
-
Per-tag usage breakdown.
|
|
815
|
-
|
|
816
|
-
**Returns**: `GetUsageByTagResponse` with `data.tags: TagUsage[]`.
|
|
817
|
-
|
|
818
|
-
```rust
|
|
819
|
-
// Rust
|
|
820
|
-
let resp = qn.admin.get_usage_by_tag(&GetUsageRequest::default()).await?;
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
```python
|
|
824
|
-
# Python
|
|
825
|
-
resp = await qn.admin.get_usage_by_tag()
|
|
826
|
-
```
|
|
827
|
-
|
|
828
|
-
```typescript
|
|
829
|
-
// Node.js
|
|
830
|
-
const resp = await qn.admin.getUsageByTag();
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
```ruby
|
|
834
|
-
# Ruby
|
|
835
|
-
resp = JSON.parse(qn.admin.get_usage_by_tag({}))
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
#### Logs
|
|
839
|
-
|
|
840
|
-
##### `get_endpoint_logs` / `getEndpointLogs`
|
|
841
|
-
|
|
842
|
-
Fetches a page of request logs for an endpoint. Set `include_details=true` for full request/response payloads (truncated at 2 KB each).
|
|
843
|
-
|
|
844
|
-
**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).
|
|
845
|
-
|
|
846
|
-
**Returns**: `GetEndpointLogsResponse` — `{ data: EndpointLog[], next_at?: string }`.
|
|
847
|
-
|
|
848
|
-
```rust
|
|
849
|
-
// Rust
|
|
850
|
-
let params = GetEndpointLogsRequest::builder()
|
|
851
|
-
.from("2026-04-01T00:00:00Z".to_string())
|
|
852
|
-
.to("2026-04-02T00:00:00Z".to_string())
|
|
853
|
-
.limit(100)
|
|
854
|
-
.build();
|
|
855
|
-
let resp = qn.admin.get_endpoint_logs("ep-123", ¶ms).await?;
|
|
856
|
-
```
|
|
857
|
-
|
|
858
|
-
```python
|
|
859
|
-
# Python
|
|
860
|
-
resp = await qn.admin.get_endpoint_logs(
|
|
861
|
-
"ep-123",
|
|
862
|
-
from_time="2026-04-01T00:00:00Z",
|
|
863
|
-
to_time="2026-04-02T00:00:00Z",
|
|
864
|
-
limit=100,
|
|
865
|
-
)
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
```typescript
|
|
869
|
-
// Node.js
|
|
870
|
-
const resp = await qn.admin.getEndpointLogs("ep-123", {
|
|
871
|
-
from: "2026-04-01T00:00:00Z",
|
|
872
|
-
to: "2026-04-02T00:00:00Z",
|
|
873
|
-
limit: 100,
|
|
874
|
-
});
|
|
875
|
-
```
|
|
876
|
-
|
|
877
|
-
```ruby
|
|
878
|
-
# Ruby
|
|
879
|
-
resp = JSON.parse(qn.admin.get_endpoint_logs(
|
|
880
|
-
id: "ep-123",
|
|
881
|
-
from_time: "2026-04-01T00:00:00Z",
|
|
882
|
-
to_time: "2026-04-02T00:00:00Z",
|
|
883
|
-
limit: 100
|
|
884
|
-
))
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
##### `get_log_details` / `getLogDetails`
|
|
888
|
-
|
|
889
|
-
Returns the full request/response payloads for a single log entry.
|
|
890
|
-
|
|
891
|
-
**Parameters**: `id` (endpoint id, required), `request_id` (log request uuid, required).
|
|
892
|
-
|
|
893
|
-
**Returns**: `GetLogDetailsResponse` with `data: LogDetails`.
|
|
894
|
-
|
|
895
|
-
```rust
|
|
896
|
-
// Rust
|
|
897
|
-
let resp = qn.admin.get_log_details("ep-123", "req-abc").await?;
|
|
898
|
-
```
|
|
899
|
-
|
|
900
|
-
```python
|
|
901
|
-
# Python
|
|
902
|
-
resp = await qn.admin.get_log_details("ep-123", "req-abc")
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
```typescript
|
|
906
|
-
// Node.js
|
|
907
|
-
const resp = await qn.admin.getLogDetails("ep-123", "req-abc");
|
|
908
|
-
```
|
|
909
|
-
|
|
910
|
-
```ruby
|
|
911
|
-
# Ruby
|
|
912
|
-
resp = JSON.parse(qn.admin.get_log_details(id: "ep-123", request_id: "req-abc"))
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
#### Endpoint Security
|
|
916
|
-
|
|
917
|
-
##### `get_endpoint_security` / `getEndpointSecurity`
|
|
918
|
-
|
|
919
|
-
Returns the full security configuration for an endpoint: tokens, JWTs, referrers, domain masks, IPs, request filters, and their per-feature toggles.
|
|
920
|
-
|
|
921
|
-
**Parameters**: `id` (string, required).
|
|
922
|
-
|
|
923
|
-
**Returns**: `GetEndpointSecurityResponse` with `data: EndpointSecurity`.
|
|
924
|
-
|
|
925
|
-
```rust
|
|
926
|
-
// Rust
|
|
927
|
-
let resp = qn.admin.get_endpoint_security("ep-123").await?;
|
|
928
|
-
```
|
|
929
|
-
|
|
930
|
-
```python
|
|
931
|
-
# Python
|
|
932
|
-
resp = await qn.admin.get_endpoint_security("ep-123")
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
```typescript
|
|
936
|
-
// Node.js
|
|
937
|
-
const resp = await qn.admin.getEndpointSecurity("ep-123");
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
```ruby
|
|
941
|
-
# Ruby
|
|
942
|
-
resp = JSON.parse(qn.admin.get_endpoint_security(id: "ep-123"))
|
|
943
|
-
```
|
|
944
|
-
|
|
945
|
-
#### Security Options
|
|
946
|
-
|
|
947
|
-
##### `get_security_options` / `getSecurityOptions`
|
|
948
|
-
|
|
949
|
-
Returns the list of security features and their enabled state for an endpoint.
|
|
950
|
-
|
|
951
|
-
**Parameters**: `id` (string, required).
|
|
952
|
-
|
|
953
|
-
**Returns**: `GetSecurityOptionsResponse` with `data: SecurityOption[]`.
|
|
954
|
-
|
|
955
|
-
```rust
|
|
956
|
-
// Rust
|
|
957
|
-
let resp = qn.admin.get_security_options("ep-123").await?;
|
|
958
|
-
```
|
|
959
|
-
|
|
960
|
-
```python
|
|
961
|
-
# Python
|
|
962
|
-
resp = await qn.admin.get_security_options("ep-123")
|
|
963
|
-
```
|
|
964
|
-
|
|
965
|
-
```typescript
|
|
966
|
-
// Node.js
|
|
967
|
-
const resp = await qn.admin.getSecurityOptions("ep-123");
|
|
968
|
-
```
|
|
969
|
-
|
|
970
|
-
```ruby
|
|
971
|
-
# Ruby
|
|
972
|
-
resp = JSON.parse(qn.admin.get_security_options(id: "ep-123"))
|
|
973
|
-
```
|
|
974
|
-
|
|
975
|
-
##### `update_security_options` / `updateSecurityOptions`
|
|
976
|
-
|
|
977
|
-
Enables or disables individual security features. Each field accepts `"enabled"` or `"disabled"`.
|
|
978
|
-
|
|
979
|
-
**Parameters**: `id` (string, required); `options`: `SecurityOptionsUpdate` (`tokens`, `referrers`, `jwts`, `ips`, `domain_masks`, `hsts`, `cors`, `request_filters`, `ip_custom_header`).
|
|
980
|
-
|
|
981
|
-
**Returns**: `UpdateSecurityOptionsResponse` with updated `SecurityOption[]`.
|
|
982
|
-
|
|
983
|
-
```rust
|
|
984
|
-
// Rust
|
|
985
|
-
let options = SecurityOptionsUpdate::builder()
|
|
986
|
-
.tokens("enabled".to_string())
|
|
987
|
-
.jwts("disabled".to_string())
|
|
988
|
-
.build();
|
|
989
|
-
let params = UpdateSecurityOptionsRequest { options };
|
|
990
|
-
qn.admin.update_security_options("ep-123", ¶ms).await?;
|
|
991
|
-
```
|
|
992
|
-
|
|
993
|
-
```python
|
|
994
|
-
# Python
|
|
995
|
-
await qn.admin.update_security_options(
|
|
996
|
-
"ep-123",
|
|
997
|
-
tokens="enabled",
|
|
998
|
-
jwts="disabled",
|
|
999
|
-
)
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
```typescript
|
|
1003
|
-
// Node.js
|
|
1004
|
-
await qn.admin.updateSecurityOptions("ep-123", {
|
|
1005
|
-
options: { tokens: "enabled", jwts: "disabled" },
|
|
1006
|
-
});
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
```ruby
|
|
1010
|
-
# Ruby
|
|
1011
|
-
qn.admin.update_security_options(id: "ep-123", tokens: "enabled", jwts: "disabled")
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
#### Tokens
|
|
1015
|
-
|
|
1016
|
-
##### `create_token` / `createToken`
|
|
1017
|
-
|
|
1018
|
-
Generates a new auth token on an endpoint.
|
|
1019
|
-
|
|
1020
|
-
**Parameters**: `id` (endpoint id, required).
|
|
1021
|
-
|
|
1022
|
-
**Returns**: nothing.
|
|
1023
|
-
|
|
1024
|
-
```rust
|
|
1025
|
-
// Rust
|
|
1026
|
-
qn.admin.create_token("ep-123").await?;
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
```python
|
|
1030
|
-
# Python
|
|
1031
|
-
await qn.admin.create_token("ep-123")
|
|
1032
|
-
```
|
|
1033
|
-
|
|
1034
|
-
```typescript
|
|
1035
|
-
// Node.js
|
|
1036
|
-
await qn.admin.createToken("ep-123");
|
|
1037
|
-
```
|
|
1038
|
-
|
|
1039
|
-
```ruby
|
|
1040
|
-
# Ruby
|
|
1041
|
-
qn.admin.create_token(id: "ep-123")
|
|
1042
|
-
```
|
|
1043
|
-
|
|
1044
|
-
##### `delete_token` / `deleteToken`
|
|
1045
|
-
|
|
1046
|
-
Revokes a token on an endpoint.
|
|
1047
|
-
|
|
1048
|
-
**Parameters**: `id` (endpoint id, required), `token_id` (string, required).
|
|
1049
|
-
|
|
1050
|
-
**Returns**: nothing.
|
|
1051
|
-
|
|
1052
|
-
```rust
|
|
1053
|
-
// Rust
|
|
1054
|
-
qn.admin.delete_token("ep-123", "tok-1").await?;
|
|
1055
|
-
```
|
|
1056
|
-
|
|
1057
|
-
```python
|
|
1058
|
-
# Python
|
|
1059
|
-
await qn.admin.delete_token("ep-123", "tok-1")
|
|
1060
|
-
```
|
|
1061
|
-
|
|
1062
|
-
```typescript
|
|
1063
|
-
// Node.js
|
|
1064
|
-
await qn.admin.deleteToken("ep-123", "tok-1");
|
|
1065
|
-
```
|
|
1066
|
-
|
|
1067
|
-
```ruby
|
|
1068
|
-
# Ruby
|
|
1069
|
-
qn.admin.delete_token(id: "ep-123", token_id: "tok-1")
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
#### Referrers
|
|
1073
|
-
|
|
1074
|
-
##### `create_referrer` / `createReferrer`
|
|
1075
|
-
|
|
1076
|
-
Whitelists a referrer URL or domain on an endpoint.
|
|
1077
|
-
|
|
1078
|
-
**Parameters**: `id` (endpoint id, required); body: `referrer` (string, optional).
|
|
1079
|
-
|
|
1080
|
-
**Returns**: nothing.
|
|
1081
|
-
|
|
1082
|
-
```rust
|
|
1083
|
-
// Rust
|
|
1084
|
-
let params = CreateReferrerRequest::builder().referrer("example.com".to_string()).build();
|
|
1085
|
-
qn.admin.create_referrer("ep-123", ¶ms).await?;
|
|
1086
|
-
```
|
|
1087
|
-
|
|
1088
|
-
```python
|
|
1089
|
-
# Python
|
|
1090
|
-
await qn.admin.create_referrer("ep-123", referrer="example.com")
|
|
1091
|
-
```
|
|
1092
|
-
|
|
1093
|
-
```typescript
|
|
1094
|
-
// Node.js
|
|
1095
|
-
await qn.admin.createReferrer("ep-123", { referrer: "example.com" });
|
|
1096
|
-
```
|
|
1097
|
-
|
|
1098
|
-
```ruby
|
|
1099
|
-
# Ruby
|
|
1100
|
-
qn.admin.create_referrer(id: "ep-123", referrer: "example.com")
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
##### `delete_referrer` / `deleteReferrer`
|
|
1104
|
-
|
|
1105
|
-
Removes a referrer from the whitelist.
|
|
1106
|
-
|
|
1107
|
-
**Parameters**: `id` (endpoint id, required), `referrer_id` (string, required).
|
|
1108
|
-
|
|
1109
|
-
**Returns**: nothing.
|
|
1110
|
-
|
|
1111
|
-
```rust
|
|
1112
|
-
// Rust
|
|
1113
|
-
qn.admin.delete_referrer("ep-123", "ref-1").await?;
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
```python
|
|
1117
|
-
# Python
|
|
1118
|
-
await qn.admin.delete_referrer("ep-123", "ref-1")
|
|
1119
|
-
```
|
|
1120
|
-
|
|
1121
|
-
```typescript
|
|
1122
|
-
// Node.js
|
|
1123
|
-
await qn.admin.deleteReferrer("ep-123", "ref-1");
|
|
1124
|
-
```
|
|
1125
|
-
|
|
1126
|
-
```ruby
|
|
1127
|
-
# Ruby
|
|
1128
|
-
qn.admin.delete_referrer(id: "ep-123", referrer_id: "ref-1")
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
|
-
#### IPs
|
|
1132
|
-
|
|
1133
|
-
##### `create_ip` / `createIp`
|
|
1134
|
-
|
|
1135
|
-
Whitelists an IP address on an endpoint.
|
|
1136
|
-
|
|
1137
|
-
**Parameters**: `id` (endpoint id, required); body: `ip` (string, optional).
|
|
1138
|
-
|
|
1139
|
-
**Returns**: nothing.
|
|
1140
|
-
|
|
1141
|
-
```rust
|
|
1142
|
-
// Rust
|
|
1143
|
-
let params = CreateIpRequest::builder().ip("198.51.100.7".to_string()).build();
|
|
1144
|
-
qn.admin.create_ip("ep-123", ¶ms).await?;
|
|
1145
|
-
```
|
|
1146
|
-
|
|
1147
|
-
```python
|
|
1148
|
-
# Python
|
|
1149
|
-
await qn.admin.create_ip("ep-123", ip="198.51.100.7")
|
|
1150
|
-
```
|
|
1151
|
-
|
|
1152
|
-
```typescript
|
|
1153
|
-
// Node.js
|
|
1154
|
-
await qn.admin.createIp("ep-123", { ip: "198.51.100.7" });
|
|
1155
|
-
```
|
|
1156
|
-
|
|
1157
|
-
```ruby
|
|
1158
|
-
# Ruby
|
|
1159
|
-
qn.admin.create_ip(id: "ep-123", ip: "198.51.100.7")
|
|
1160
|
-
```
|
|
1161
|
-
|
|
1162
|
-
##### `delete_ip` / `deleteIp`
|
|
1163
|
-
|
|
1164
|
-
Removes an IP from the whitelist.
|
|
1165
|
-
|
|
1166
|
-
**Parameters**: `id` (endpoint id, required), `ip_id` (string, required).
|
|
1167
|
-
|
|
1168
|
-
**Returns**: `DeleteBoolResponse`.
|
|
1169
|
-
|
|
1170
|
-
```rust
|
|
1171
|
-
// Rust
|
|
1172
|
-
qn.admin.delete_ip("ep-123", "ip-1").await?;
|
|
1173
|
-
```
|
|
1174
|
-
|
|
1175
|
-
```python
|
|
1176
|
-
# Python
|
|
1177
|
-
await qn.admin.delete_ip("ep-123", "ip-1")
|
|
1178
|
-
```
|
|
1179
|
-
|
|
1180
|
-
```typescript
|
|
1181
|
-
// Node.js
|
|
1182
|
-
await qn.admin.deleteIp("ep-123", "ip-1");
|
|
1183
|
-
```
|
|
1184
|
-
|
|
1185
|
-
```ruby
|
|
1186
|
-
# Ruby
|
|
1187
|
-
resp = JSON.parse(qn.admin.delete_ip(id: "ep-123", ip_id: "ip-1"))
|
|
1188
|
-
```
|
|
1189
|
-
|
|
1190
|
-
#### Domain Masks
|
|
1191
|
-
|
|
1192
|
-
##### `create_domain_mask` / `createDomainMask`
|
|
1193
|
-
|
|
1194
|
-
Adds a custom domain mask to an endpoint.
|
|
1195
|
-
|
|
1196
|
-
**Parameters**: `id` (endpoint id, required); body: `domain_mask` (string, optional).
|
|
1197
|
-
|
|
1198
|
-
**Returns**: nothing.
|
|
1199
|
-
|
|
1200
|
-
```rust
|
|
1201
|
-
// Rust
|
|
1202
|
-
let params = CreateDomainMaskRequest::builder()
|
|
1203
|
-
.domain_mask("rpc.example.com".to_string())
|
|
1204
|
-
.build();
|
|
1205
|
-
qn.admin.create_domain_mask("ep-123", ¶ms).await?;
|
|
1206
|
-
```
|
|
1207
|
-
|
|
1208
|
-
```python
|
|
1209
|
-
# Python
|
|
1210
|
-
await qn.admin.create_domain_mask("ep-123", domain_mask="rpc.example.com")
|
|
1211
|
-
```
|
|
1212
|
-
|
|
1213
|
-
```typescript
|
|
1214
|
-
// Node.js
|
|
1215
|
-
await qn.admin.createDomainMask("ep-123", { domainMask: "rpc.example.com" });
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
```ruby
|
|
1219
|
-
# Ruby
|
|
1220
|
-
qn.admin.create_domain_mask(id: "ep-123", domain_mask: "rpc.example.com")
|
|
1221
|
-
```
|
|
1222
|
-
|
|
1223
|
-
##### `delete_domain_mask` / `deleteDomainMask`
|
|
1224
|
-
|
|
1225
|
-
Removes a domain mask.
|
|
1226
|
-
|
|
1227
|
-
**Parameters**: `id` (endpoint id, required), `domain_mask_id` (string, required).
|
|
1228
|
-
|
|
1229
|
-
**Returns**: nothing.
|
|
1230
|
-
|
|
1231
|
-
```rust
|
|
1232
|
-
// Rust
|
|
1233
|
-
qn.admin.delete_domain_mask("ep-123", "dm-1").await?;
|
|
1234
|
-
```
|
|
1235
|
-
|
|
1236
|
-
```python
|
|
1237
|
-
# Python
|
|
1238
|
-
await qn.admin.delete_domain_mask("ep-123", "dm-1")
|
|
1239
|
-
```
|
|
1240
|
-
|
|
1241
|
-
```typescript
|
|
1242
|
-
// Node.js
|
|
1243
|
-
await qn.admin.deleteDomainMask("ep-123", "dm-1");
|
|
1244
|
-
```
|
|
1245
|
-
|
|
1246
|
-
```ruby
|
|
1247
|
-
# Ruby
|
|
1248
|
-
qn.admin.delete_domain_mask(id: "ep-123", domain_mask_id: "dm-1")
|
|
1249
|
-
```
|
|
1250
|
-
|
|
1251
|
-
#### JWTs
|
|
1252
|
-
|
|
1253
|
-
##### `create_jwt` / `createJwt`
|
|
1254
|
-
|
|
1255
|
-
Configures JWT validation on an endpoint.
|
|
1256
|
-
|
|
1257
|
-
**Parameters**: `id` (endpoint id, required); body: `public_key` (string, optional), `kid` (string, optional), `name` (string, optional).
|
|
1258
|
-
|
|
1259
|
-
**Returns**: nothing.
|
|
1260
|
-
|
|
1261
|
-
```rust
|
|
1262
|
-
// Rust
|
|
1263
|
-
let params = CreateJwtRequest::builder()
|
|
1264
|
-
.public_key("-----BEGIN PUBLIC KEY-----\n...".to_string())
|
|
1265
|
-
.kid("key-1".to_string())
|
|
1266
|
-
.name("primary".to_string())
|
|
1267
|
-
.build();
|
|
1268
|
-
qn.admin.create_jwt("ep-123", ¶ms).await?;
|
|
1269
|
-
```
|
|
1270
|
-
|
|
1271
|
-
```python
|
|
1272
|
-
# Python
|
|
1273
|
-
await qn.admin.create_jwt(
|
|
1274
|
-
"ep-123",
|
|
1275
|
-
public_key="-----BEGIN PUBLIC KEY-----\n...",
|
|
1276
|
-
kid="key-1",
|
|
1277
|
-
name="primary",
|
|
1278
|
-
)
|
|
1279
|
-
```
|
|
1280
|
-
|
|
1281
|
-
```typescript
|
|
1282
|
-
// Node.js
|
|
1283
|
-
await qn.admin.createJwt("ep-123", {
|
|
1284
|
-
publicKey: "-----BEGIN PUBLIC KEY-----\n...",
|
|
1285
|
-
kid: "key-1",
|
|
1286
|
-
name: "primary",
|
|
1287
|
-
});
|
|
1288
|
-
```
|
|
1289
|
-
|
|
1290
|
-
```ruby
|
|
1291
|
-
# Ruby
|
|
1292
|
-
qn.admin.create_jwt(
|
|
1293
|
-
id: "ep-123",
|
|
1294
|
-
public_key: "-----BEGIN PUBLIC KEY-----\n...",
|
|
1295
|
-
kid: "key-1",
|
|
1296
|
-
name: "primary"
|
|
1297
|
-
)
|
|
1298
|
-
```
|
|
1299
|
-
|
|
1300
|
-
##### `delete_jwt` / `deleteJwt`
|
|
1301
|
-
|
|
1302
|
-
Removes a JWT configuration.
|
|
1303
|
-
|
|
1304
|
-
**Parameters**: `id` (endpoint id, required), `jwt_id` (string, required).
|
|
1305
|
-
|
|
1306
|
-
**Returns**: nothing.
|
|
1307
|
-
|
|
1308
|
-
```rust
|
|
1309
|
-
// Rust
|
|
1310
|
-
qn.admin.delete_jwt("ep-123", "jwt-1").await?;
|
|
1311
|
-
```
|
|
1312
|
-
|
|
1313
|
-
```python
|
|
1314
|
-
# Python
|
|
1315
|
-
await qn.admin.delete_jwt("ep-123", "jwt-1")
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
```typescript
|
|
1319
|
-
// Node.js
|
|
1320
|
-
await qn.admin.deleteJwt("ep-123", "jwt-1");
|
|
1321
|
-
```
|
|
1322
|
-
|
|
1323
|
-
```ruby
|
|
1324
|
-
# Ruby
|
|
1325
|
-
qn.admin.delete_jwt(id: "ep-123", jwt_id: "jwt-1")
|
|
1326
|
-
```
|
|
1327
|
-
|
|
1328
|
-
#### Request Filters
|
|
1329
|
-
|
|
1330
|
-
Whitelist specific RPC methods on an endpoint. Requests for methods not on the list are blocked when the feature is enabled.
|
|
1331
|
-
|
|
1332
|
-
##### `create_request_filter` / `createRequestFilter`
|
|
1333
|
-
|
|
1334
|
-
**Parameters**: `id` (endpoint id, required); body: `method` (string[], optional). Ruby's Hash key is `methods` (plural).
|
|
1335
|
-
|
|
1336
|
-
**Returns**: `CreateRequestFilterResponse` with `data.id`.
|
|
1337
|
-
|
|
1338
|
-
```rust
|
|
1339
|
-
// Rust
|
|
1340
|
-
let params = CreateRequestFilterRequest::builder()
|
|
1341
|
-
.method(vec!["eth_blockNumber".to_string(), "eth_getBalance".to_string()])
|
|
1342
|
-
.build();
|
|
1343
|
-
let resp = qn.admin.create_request_filter("ep-123", ¶ms).await?;
|
|
1344
|
-
```
|
|
1345
|
-
|
|
1346
|
-
```python
|
|
1347
|
-
# Python
|
|
1348
|
-
resp = await qn.admin.create_request_filter(
|
|
1349
|
-
"ep-123",
|
|
1350
|
-
method=["eth_blockNumber", "eth_getBalance"],
|
|
1351
|
-
)
|
|
1352
|
-
```
|
|
1353
|
-
|
|
1354
|
-
```typescript
|
|
1355
|
-
// Node.js
|
|
1356
|
-
const resp = await qn.admin.createRequestFilter("ep-123", {
|
|
1357
|
-
method: ["eth_blockNumber", "eth_getBalance"],
|
|
1358
|
-
});
|
|
1359
|
-
```
|
|
1360
|
-
|
|
1361
|
-
```ruby
|
|
1362
|
-
# Ruby
|
|
1363
|
-
resp = JSON.parse(qn.admin.create_request_filter(
|
|
1364
|
-
id: "ep-123",
|
|
1365
|
-
methods: ["eth_blockNumber", "eth_getBalance"]
|
|
1366
|
-
))
|
|
1367
|
-
```
|
|
1368
|
-
|
|
1369
|
-
##### `update_request_filter` / `updateRequestFilter`
|
|
1370
|
-
|
|
1371
|
-
**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).
|
|
1372
|
-
|
|
1373
|
-
**Returns**: nothing.
|
|
1374
|
-
|
|
1375
|
-
```rust
|
|
1376
|
-
// Rust
|
|
1377
|
-
let params = UpdateRequestFilterRequest::builder()
|
|
1378
|
-
.method(vec!["eth_call".to_string()])
|
|
1379
|
-
.build();
|
|
1380
|
-
qn.admin.update_request_filter("ep-123", "f-1", ¶ms).await?;
|
|
1381
|
-
```
|
|
1382
|
-
|
|
1383
|
-
```python
|
|
1384
|
-
# Python
|
|
1385
|
-
await qn.admin.update_request_filter("ep-123", "f-1", method=["eth_call"])
|
|
1386
|
-
```
|
|
1387
|
-
|
|
1388
|
-
```typescript
|
|
1389
|
-
// Node.js
|
|
1390
|
-
await qn.admin.updateRequestFilter("ep-123", "f-1", { method: ["eth_call"] });
|
|
1391
|
-
```
|
|
1392
|
-
|
|
1393
|
-
```ruby
|
|
1394
|
-
# Ruby
|
|
1395
|
-
qn.admin.update_request_filter(id: "ep-123", request_filter_id: "f-1", methods: ["eth_call"])
|
|
1396
|
-
```
|
|
1397
|
-
|
|
1398
|
-
##### `delete_request_filter` / `deleteRequestFilter`
|
|
1399
|
-
|
|
1400
|
-
**Parameters**: `id` (endpoint id, required), `request_filter_id` (string, required).
|
|
1401
|
-
|
|
1402
|
-
**Returns**: nothing.
|
|
1403
|
-
|
|
1404
|
-
```rust
|
|
1405
|
-
// Rust
|
|
1406
|
-
qn.admin.delete_request_filter("ep-123", "f-1").await?;
|
|
1407
|
-
```
|
|
1408
|
-
|
|
1409
|
-
```python
|
|
1410
|
-
# Python
|
|
1411
|
-
await qn.admin.delete_request_filter("ep-123", "f-1")
|
|
1412
|
-
```
|
|
1413
|
-
|
|
1414
|
-
```typescript
|
|
1415
|
-
// Node.js
|
|
1416
|
-
await qn.admin.deleteRequestFilter("ep-123", "f-1");
|
|
1417
|
-
```
|
|
1418
|
-
|
|
1419
|
-
```ruby
|
|
1420
|
-
# Ruby
|
|
1421
|
-
qn.admin.delete_request_filter(id: "ep-123", request_filter_id: "f-1")
|
|
1422
|
-
```
|
|
1423
|
-
|
|
1424
|
-
#### Multichain
|
|
1425
|
-
|
|
1426
|
-
##### `enable_multichain` / `enableMultichain`
|
|
1427
|
-
|
|
1428
|
-
Enables multichain on an endpoint.
|
|
1429
|
-
|
|
1430
|
-
**Parameters**: `id` (endpoint id, required).
|
|
1431
|
-
|
|
1432
|
-
**Returns**: nothing.
|
|
1433
|
-
|
|
1434
|
-
```rust
|
|
1435
|
-
// Rust
|
|
1436
|
-
qn.admin.enable_multichain("ep-123").await?;
|
|
1437
|
-
```
|
|
1438
|
-
|
|
1439
|
-
```python
|
|
1440
|
-
# Python
|
|
1441
|
-
await qn.admin.enable_multichain("ep-123")
|
|
1442
|
-
```
|
|
1443
|
-
|
|
1444
|
-
```typescript
|
|
1445
|
-
// Node.js
|
|
1446
|
-
await qn.admin.enableMultichain("ep-123");
|
|
1447
|
-
```
|
|
1448
|
-
|
|
1449
|
-
```ruby
|
|
1450
|
-
# Ruby
|
|
1451
|
-
qn.admin.enable_multichain(id: "ep-123")
|
|
1452
|
-
```
|
|
1453
|
-
|
|
1454
|
-
##### `disable_multichain` / `disableMultichain`
|
|
1455
|
-
|
|
1456
|
-
Disables multichain on an endpoint.
|
|
1457
|
-
|
|
1458
|
-
**Parameters**: `id` (endpoint id, required).
|
|
1459
|
-
|
|
1460
|
-
**Returns**: nothing.
|
|
1461
|
-
|
|
1462
|
-
```rust
|
|
1463
|
-
// Rust
|
|
1464
|
-
qn.admin.disable_multichain("ep-123").await?;
|
|
1465
|
-
```
|
|
1466
|
-
|
|
1467
|
-
```python
|
|
1468
|
-
# Python
|
|
1469
|
-
await qn.admin.disable_multichain("ep-123")
|
|
1470
|
-
```
|
|
1471
|
-
|
|
1472
|
-
```typescript
|
|
1473
|
-
// Node.js
|
|
1474
|
-
await qn.admin.disableMultichain("ep-123");
|
|
1475
|
-
```
|
|
1476
|
-
|
|
1477
|
-
```ruby
|
|
1478
|
-
# Ruby
|
|
1479
|
-
qn.admin.disable_multichain(id: "ep-123")
|
|
1480
|
-
```
|
|
1481
|
-
|
|
1482
|
-
#### IP Custom Headers
|
|
1483
|
-
|
|
1484
|
-
##### `create_or_update_ip_custom_header` / `createOrUpdateIpCustomHeader`
|
|
1485
|
-
|
|
1486
|
-
Sets the custom header used to identify the client IP (e.g. when traffic is proxied).
|
|
1487
|
-
|
|
1488
|
-
**Parameters**: `id` (endpoint id, required); body: `header_name` (string, required).
|
|
1489
|
-
|
|
1490
|
-
**Returns**: `CreateOrUpdateIpCustomHeaderResponse` with `data.header_name`.
|
|
1491
|
-
|
|
1492
|
-
```rust
|
|
1493
|
-
// Rust
|
|
1494
|
-
let params = CreateOrUpdateIpCustomHeaderRequest::builder()
|
|
1495
|
-
.header_name("X-Forwarded-For".to_string())
|
|
1496
|
-
.build();
|
|
1497
|
-
qn.admin.create_or_update_ip_custom_header("ep-123", ¶ms).await?;
|
|
1498
|
-
```
|
|
1499
|
-
|
|
1500
|
-
```python
|
|
1501
|
-
# Python
|
|
1502
|
-
await qn.admin.create_or_update_ip_custom_header("ep-123", header_name="X-Forwarded-For")
|
|
1503
|
-
```
|
|
1504
|
-
|
|
1505
|
-
```typescript
|
|
1506
|
-
// Node.js
|
|
1507
|
-
await qn.admin.createOrUpdateIpCustomHeader("ep-123", { headerName: "X-Forwarded-For" });
|
|
1508
|
-
```
|
|
1509
|
-
|
|
1510
|
-
```ruby
|
|
1511
|
-
# Ruby
|
|
1512
|
-
JSON.parse(qn.admin.create_or_update_ip_custom_header(
|
|
1513
|
-
id: "ep-123",
|
|
1514
|
-
header_name: "X-Forwarded-For"
|
|
1515
|
-
))
|
|
1516
|
-
```
|
|
1517
|
-
|
|
1518
|
-
##### `delete_ip_custom_header` / `deleteIpCustomHeader`
|
|
1519
|
-
|
|
1520
|
-
Removes the custom IP header configuration.
|
|
1521
|
-
|
|
1522
|
-
**Parameters**: `id` (endpoint id, required).
|
|
1523
|
-
|
|
1524
|
-
**Returns**: `DeleteBoolResponse`.
|
|
1525
|
-
|
|
1526
|
-
```rust
|
|
1527
|
-
// Rust
|
|
1528
|
-
qn.admin.delete_ip_custom_header("ep-123").await?;
|
|
1529
|
-
```
|
|
1530
|
-
|
|
1531
|
-
```python
|
|
1532
|
-
# Python
|
|
1533
|
-
await qn.admin.delete_ip_custom_header("ep-123")
|
|
1534
|
-
```
|
|
1535
|
-
|
|
1536
|
-
```typescript
|
|
1537
|
-
// Node.js
|
|
1538
|
-
await qn.admin.deleteIpCustomHeader("ep-123");
|
|
1539
|
-
```
|
|
1540
|
-
|
|
1541
|
-
```ruby
|
|
1542
|
-
# Ruby
|
|
1543
|
-
JSON.parse(qn.admin.delete_ip_custom_header(id: "ep-123"))
|
|
1544
|
-
```
|
|
1545
|
-
|
|
1546
|
-
#### Method Rate Limits
|
|
1547
|
-
|
|
1548
|
-
##### `get_method_rate_limits` / `getMethodRateLimits`
|
|
1549
|
-
|
|
1550
|
-
Lists method-level rate limiters configured on an endpoint.
|
|
1551
|
-
|
|
1552
|
-
**Parameters**: `id` (endpoint id, required).
|
|
1553
|
-
|
|
1554
|
-
**Returns**: `GetMethodRateLimitsResponse` with `data.rate_limiters: MethodRateLimiter[]`.
|
|
1555
|
-
|
|
1556
|
-
```rust
|
|
1557
|
-
// Rust
|
|
1558
|
-
let resp = qn.admin.get_method_rate_limits("ep-123").await?;
|
|
1559
|
-
```
|
|
1560
|
-
|
|
1561
|
-
```python
|
|
1562
|
-
# Python
|
|
1563
|
-
resp = await qn.admin.get_method_rate_limits("ep-123")
|
|
1564
|
-
```
|
|
1565
|
-
|
|
1566
|
-
```typescript
|
|
1567
|
-
// Node.js
|
|
1568
|
-
const resp = await qn.admin.getMethodRateLimits("ep-123");
|
|
1569
|
-
```
|
|
1570
|
-
|
|
1571
|
-
```ruby
|
|
1572
|
-
# Ruby
|
|
1573
|
-
resp = JSON.parse(qn.admin.get_method_rate_limits(id: "ep-123"))
|
|
1574
|
-
```
|
|
1575
|
-
|
|
1576
|
-
##### `create_method_rate_limit` / `createMethodRateLimit`
|
|
1577
|
-
|
|
1578
|
-
Creates a new method-level rate limiter.
|
|
1579
|
-
|
|
1580
|
-
**Parameters**: `id` (endpoint id, required); body: `interval` (string, e.g. `"second"`), `methods` (string[]), `rate` (i32).
|
|
1581
|
-
|
|
1582
|
-
**Returns**: `CreateMethodRateLimitResponse` with `data: MethodRateLimiter`.
|
|
1583
|
-
|
|
1584
|
-
```rust
|
|
1585
|
-
// Rust
|
|
1586
|
-
let params = CreateMethodRateLimitRequest::builder()
|
|
1587
|
-
.interval("second".to_string())
|
|
1588
|
-
.methods(vec!["eth_call".to_string()])
|
|
1589
|
-
.rate(10)
|
|
1590
|
-
.build();
|
|
1591
|
-
let resp = qn.admin.create_method_rate_limit("ep-123", ¶ms).await?;
|
|
1592
|
-
```
|
|
1593
|
-
|
|
1594
|
-
```python
|
|
1595
|
-
# Python
|
|
1596
|
-
resp = await qn.admin.create_method_rate_limit(
|
|
1597
|
-
"ep-123",
|
|
1598
|
-
interval="second",
|
|
1599
|
-
methods=["eth_call"],
|
|
1600
|
-
rate=10,
|
|
1601
|
-
)
|
|
1602
|
-
```
|
|
1603
|
-
|
|
1604
|
-
```typescript
|
|
1605
|
-
// Node.js
|
|
1606
|
-
const resp = await qn.admin.createMethodRateLimit("ep-123", {
|
|
1607
|
-
interval: "second",
|
|
1608
|
-
methods: ["eth_call"],
|
|
1609
|
-
rate: 10,
|
|
1610
|
-
});
|
|
1611
|
-
```
|
|
1612
|
-
|
|
1613
|
-
```ruby
|
|
1614
|
-
# Ruby
|
|
1615
|
-
resp = JSON.parse(qn.admin.create_method_rate_limit(
|
|
1616
|
-
id: "ep-123",
|
|
1617
|
-
interval: "second",
|
|
1618
|
-
methods: ["eth_call"],
|
|
1619
|
-
rate: 10
|
|
1620
|
-
))
|
|
1621
|
-
```
|
|
1622
|
-
|
|
1623
|
-
##### `update_method_rate_limit` / `updateMethodRateLimit`
|
|
1624
|
-
|
|
1625
|
-
Updates an existing rate limiter. Only provided fields change.
|
|
1626
|
-
|
|
1627
|
-
**Parameters**: `id` (endpoint id, required), `method_rate_limit_id` (string, required); body: `methods` (string[], optional), `status` (`"enabled"` | `"disabled"`, optional), `rate` (i32, optional).
|
|
1628
|
-
|
|
1629
|
-
**Returns**: `UpdateMethodRateLimitResponse`.
|
|
1630
|
-
|
|
1631
|
-
```rust
|
|
1632
|
-
// Rust
|
|
1633
|
-
let params = UpdateMethodRateLimitRequest::builder().rate(50).build();
|
|
1634
|
-
qn.admin.update_method_rate_limit("ep-123", "rl-1", ¶ms).await?;
|
|
1635
|
-
```
|
|
1636
|
-
|
|
1637
|
-
```python
|
|
1638
|
-
# Python
|
|
1639
|
-
await qn.admin.update_method_rate_limit("ep-123", "rl-1", rate=50)
|
|
1640
|
-
```
|
|
1641
|
-
|
|
1642
|
-
```typescript
|
|
1643
|
-
// Node.js
|
|
1644
|
-
await qn.admin.updateMethodRateLimit("ep-123", "rl-1", { rate: 50 });
|
|
1645
|
-
```
|
|
1646
|
-
|
|
1647
|
-
```ruby
|
|
1648
|
-
# Ruby
|
|
1649
|
-
JSON.parse(qn.admin.update_method_rate_limit(id: "ep-123", method_rate_limit_id: "rl-1", rate: 50))
|
|
1650
|
-
```
|
|
1651
|
-
|
|
1652
|
-
##### `delete_method_rate_limit` / `deleteMethodRateLimit`
|
|
1653
|
-
|
|
1654
|
-
Deletes a rate limiter.
|
|
1655
|
-
|
|
1656
|
-
**Parameters**: `id` (endpoint id, required), `method_rate_limit_id` (string, required).
|
|
1657
|
-
|
|
1658
|
-
**Returns**: nothing.
|
|
1659
|
-
|
|
1660
|
-
```rust
|
|
1661
|
-
// Rust
|
|
1662
|
-
qn.admin.delete_method_rate_limit("ep-123", "rl-1").await?;
|
|
1663
|
-
```
|
|
1664
|
-
|
|
1665
|
-
```python
|
|
1666
|
-
# Python
|
|
1667
|
-
await qn.admin.delete_method_rate_limit("ep-123", "rl-1")
|
|
1668
|
-
```
|
|
1669
|
-
|
|
1670
|
-
```typescript
|
|
1671
|
-
// Node.js
|
|
1672
|
-
await qn.admin.deleteMethodRateLimit("ep-123", "rl-1");
|
|
1673
|
-
```
|
|
1674
|
-
|
|
1675
|
-
```ruby
|
|
1676
|
-
# Ruby
|
|
1677
|
-
qn.admin.delete_method_rate_limit(id: "ep-123", method_rate_limit_id: "rl-1")
|
|
1678
|
-
```
|
|
1679
|
-
|
|
1680
|
-
#### Endpoint Rate Limits
|
|
1681
|
-
|
|
1682
|
-
##### `update_rate_limits` / `updateRateLimits`
|
|
1683
|
-
|
|
1684
|
-
Updates the endpoint-level RPS / RPM / RPD caps.
|
|
1685
|
-
|
|
1686
|
-
**Parameters**: `id` (endpoint id, required); `rate_limits`: `RateLimitSettings` (`rps`, `rpm`, `rpd`, all optional).
|
|
1687
|
-
|
|
1688
|
-
**Returns**: nothing.
|
|
1689
|
-
|
|
1690
|
-
```rust
|
|
1691
|
-
// Rust
|
|
1692
|
-
let rate_limits = RateLimitSettings::builder().rps(100).rpm(5000).build();
|
|
1693
|
-
let params = UpdateRateLimitsRequest { rate_limits };
|
|
1694
|
-
qn.admin.update_rate_limits("ep-123", ¶ms).await?;
|
|
1695
|
-
```
|
|
1696
|
-
|
|
1697
|
-
```python
|
|
1698
|
-
# Python
|
|
1699
|
-
await qn.admin.update_rate_limits("ep-123", rps=100, rpm=5000)
|
|
1700
|
-
```
|
|
1701
|
-
|
|
1702
|
-
```typescript
|
|
1703
|
-
// Node.js
|
|
1704
|
-
await qn.admin.updateRateLimits("ep-123", { rateLimits: { rps: 100, rpm: 5000 } });
|
|
1705
|
-
```
|
|
1706
|
-
|
|
1707
|
-
```ruby
|
|
1708
|
-
# Ruby
|
|
1709
|
-
qn.admin.update_rate_limits(id: "ep-123", rps: 100, rpm: 5000)
|
|
1710
|
-
```
|
|
1711
|
-
|
|
1712
|
-
#### Metrics
|
|
1713
|
-
|
|
1714
|
-
##### `get_endpoint_metrics` / `getEndpointMetrics`
|
|
1715
|
-
|
|
1716
|
-
Returns metric series for an endpoint over a time period.
|
|
1717
|
-
|
|
1718
|
-
**Parameters**: `id` (endpoint id, required); body: `period` (`"hour"` | `"day"` | `"week"` | `"month"`), `metric` (e.g. `"method_calls_over_time"`, `"response_status_breakdown"`).
|
|
1719
|
-
|
|
1720
|
-
**Returns**: `GetEndpointMetricsResponse` with `data: EndpointMetric[]`.
|
|
1721
|
-
|
|
1722
|
-
```rust
|
|
1723
|
-
// Rust
|
|
1724
|
-
let params = GetEndpointMetricsRequest {
|
|
1725
|
-
period: "day".to_string(),
|
|
1726
|
-
metric: "method_calls_over_time".to_string(),
|
|
1727
|
-
};
|
|
1728
|
-
let resp = qn.admin.get_endpoint_metrics("ep-123", ¶ms).await?;
|
|
1729
|
-
```
|
|
1730
|
-
|
|
1731
|
-
```python
|
|
1732
|
-
# Python
|
|
1733
|
-
resp = await qn.admin.get_endpoint_metrics(
|
|
1734
|
-
"ep-123",
|
|
1735
|
-
period="day",
|
|
1736
|
-
metric="method_calls_over_time",
|
|
1737
|
-
)
|
|
1738
|
-
```
|
|
1739
|
-
|
|
1740
|
-
```typescript
|
|
1741
|
-
// Node.js
|
|
1742
|
-
const resp = await qn.admin.getEndpointMetrics("ep-123", {
|
|
1743
|
-
period: "day",
|
|
1744
|
-
metric: "method_calls_over_time",
|
|
1745
|
-
});
|
|
1746
|
-
```
|
|
1747
|
-
|
|
1748
|
-
```ruby
|
|
1749
|
-
# Ruby
|
|
1750
|
-
resp = JSON.parse(qn.admin.get_endpoint_metrics(
|
|
1751
|
-
id: "ep-123",
|
|
1752
|
-
period: "day",
|
|
1753
|
-
metric: "method_calls_over_time"
|
|
1754
|
-
))
|
|
1755
|
-
```
|
|
1756
|
-
|
|
1757
|
-
##### `get_account_metrics` / `getAccountMetrics`
|
|
1758
|
-
|
|
1759
|
-
Returns account-level metric series. Supports an optional `percentile` (e.g. `"p50"`, `"p95"`, `"p99"`) for latency metrics.
|
|
1760
|
-
|
|
1761
|
-
**Parameters**: `period` (required), `metric` (required), `percentile` (string, optional).
|
|
1762
|
-
|
|
1763
|
-
**Returns**: `GetAccountMetricsResponse` with `data: EndpointMetric[]`.
|
|
1764
|
-
|
|
1765
|
-
```rust
|
|
1766
|
-
// Rust
|
|
1767
|
-
let params = GetAccountMetricsRequest {
|
|
1768
|
-
period: "day".to_string(),
|
|
1769
|
-
metric: "credits_over_time".to_string(),
|
|
1770
|
-
percentile: None,
|
|
1771
|
-
};
|
|
1772
|
-
let resp = qn.admin.get_account_metrics(¶ms).await?;
|
|
1773
|
-
```
|
|
1774
|
-
|
|
1775
|
-
```python
|
|
1776
|
-
# Python
|
|
1777
|
-
resp = await qn.admin.get_account_metrics(period="day", metric="credits_over_time")
|
|
1778
|
-
```
|
|
1779
|
-
|
|
1780
|
-
```typescript
|
|
1781
|
-
// Node.js
|
|
1782
|
-
const resp = await qn.admin.getAccountMetrics({
|
|
1783
|
-
period: "day",
|
|
1784
|
-
metric: "credits_over_time",
|
|
1785
|
-
});
|
|
1786
|
-
```
|
|
1787
|
-
|
|
1788
|
-
```ruby
|
|
1789
|
-
# Ruby
|
|
1790
|
-
resp = JSON.parse(qn.admin.get_account_metrics(period: "day", metric: "credits_over_time"))
|
|
1791
|
-
```
|
|
1792
|
-
|
|
1793
|
-
#### Chains
|
|
1794
|
-
|
|
1795
|
-
##### `list_chains` / `listChains`
|
|
1796
|
-
|
|
1797
|
-
Lists the blockchains supported by QuickNode along with their networks.
|
|
1798
|
-
|
|
1799
|
-
**Parameters**: none.
|
|
1800
|
-
|
|
1801
|
-
**Returns**: `ListChainsResponse` with `data: Chain[]`.
|
|
1802
|
-
|
|
1803
|
-
```rust
|
|
1804
|
-
// Rust
|
|
1805
|
-
let resp = qn.admin.list_chains().await?;
|
|
1806
|
-
```
|
|
1807
|
-
|
|
1808
|
-
```python
|
|
1809
|
-
# Python
|
|
1810
|
-
resp = await qn.admin.list_chains()
|
|
1811
|
-
```
|
|
1812
|
-
|
|
1813
|
-
```typescript
|
|
1814
|
-
// Node.js
|
|
1815
|
-
const resp = await qn.admin.listChains();
|
|
1816
|
-
```
|
|
1817
|
-
|
|
1818
|
-
```ruby
|
|
1819
|
-
# Ruby
|
|
1820
|
-
resp = JSON.parse(qn.admin.list_chains)
|
|
1821
|
-
```
|
|
1822
|
-
|
|
1823
|
-
#### Billing
|
|
1824
|
-
|
|
1825
|
-
##### `list_invoices` / `listInvoices`
|
|
1826
|
-
|
|
1827
|
-
Lists invoices on the account.
|
|
1828
|
-
|
|
1829
|
-
**Parameters**: none.
|
|
1830
|
-
|
|
1831
|
-
**Returns**: `ListInvoicesResponse` with `data.invoices: Invoice[]`.
|
|
1832
|
-
|
|
1833
|
-
```rust
|
|
1834
|
-
// Rust
|
|
1835
|
-
let resp = qn.admin.list_invoices().await?;
|
|
1836
|
-
```
|
|
1837
|
-
|
|
1838
|
-
```python
|
|
1839
|
-
# Python
|
|
1840
|
-
resp = await qn.admin.list_invoices()
|
|
1841
|
-
```
|
|
1842
|
-
|
|
1843
|
-
```typescript
|
|
1844
|
-
// Node.js
|
|
1845
|
-
const resp = await qn.admin.listInvoices();
|
|
1846
|
-
```
|
|
1847
|
-
|
|
1848
|
-
```ruby
|
|
1849
|
-
# Ruby
|
|
1850
|
-
resp = JSON.parse(qn.admin.list_invoices)
|
|
1851
|
-
```
|
|
1852
|
-
|
|
1853
|
-
##### `list_payments` / `listPayments`
|
|
1854
|
-
|
|
1855
|
-
Lists payments on the account.
|
|
1856
|
-
|
|
1857
|
-
**Parameters**: none.
|
|
1858
|
-
|
|
1859
|
-
**Returns**: `ListPaymentsResponse` with `data.payments: Payment[]`.
|
|
1860
|
-
|
|
1861
|
-
```rust
|
|
1862
|
-
// Rust
|
|
1863
|
-
let resp = qn.admin.list_payments().await?;
|
|
1864
|
-
```
|
|
1865
|
-
|
|
1866
|
-
```python
|
|
1867
|
-
# Python
|
|
1868
|
-
resp = await qn.admin.list_payments()
|
|
1869
|
-
```
|
|
1870
|
-
|
|
1871
|
-
```typescript
|
|
1872
|
-
// Node.js
|
|
1873
|
-
const resp = await qn.admin.listPayments();
|
|
1874
|
-
```
|
|
1875
|
-
|
|
1876
|
-
```ruby
|
|
1877
|
-
# Ruby
|
|
1878
|
-
resp = JSON.parse(qn.admin.list_payments)
|
|
1879
|
-
```
|
|
1880
|
-
|
|
1881
|
-
#### Bulk Operations
|
|
1882
|
-
|
|
1883
|
-
##### `bulk_update_endpoint_status` / `bulkUpdateEndpointStatus`
|
|
1884
|
-
|
|
1885
|
-
Activates or pauses many endpoints at once.
|
|
1886
|
-
|
|
1887
|
-
**Parameters**: `ids` (string[], required), `status` (`"active"` | `"paused"`, required).
|
|
1888
|
-
|
|
1889
|
-
**Returns**: `BulkUpdateEndpointStatusResponse` with per-endpoint `results`.
|
|
1890
|
-
|
|
1891
|
-
```rust
|
|
1892
|
-
// Rust
|
|
1893
|
-
let params = BulkUpdateEndpointStatusRequest::builder()
|
|
1894
|
-
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
|
|
1895
|
-
.status("paused".to_string())
|
|
1896
|
-
.build();
|
|
1897
|
-
let resp = qn.admin.bulk_update_endpoint_status(¶ms).await?;
|
|
1898
|
-
```
|
|
1899
|
-
|
|
1900
|
-
```python
|
|
1901
|
-
# Python
|
|
1902
|
-
resp = await qn.admin.bulk_update_endpoint_status(ids=["ep-1", "ep-2"], status="paused")
|
|
1903
|
-
```
|
|
1904
|
-
|
|
1905
|
-
```typescript
|
|
1906
|
-
// Node.js
|
|
1907
|
-
const resp = await qn.admin.bulkUpdateEndpointStatus({
|
|
1908
|
-
ids: ["ep-1", "ep-2"],
|
|
1909
|
-
status: "paused",
|
|
1910
|
-
});
|
|
1911
|
-
```
|
|
1912
|
-
|
|
1913
|
-
```ruby
|
|
1914
|
-
# Ruby
|
|
1915
|
-
resp = JSON.parse(qn.admin.bulk_update_endpoint_status(ids: ["ep-1", "ep-2"], status: "paused"))
|
|
1916
|
-
```
|
|
1917
|
-
|
|
1918
|
-
##### `bulk_add_tag` / `bulkAddTag`
|
|
1919
|
-
|
|
1920
|
-
Applies a tag (created if missing) to many endpoints at once.
|
|
1921
|
-
|
|
1922
|
-
**Parameters**: `ids` (string[], required), `label` (string, required).
|
|
1923
|
-
|
|
1924
|
-
**Returns**: `BulkAddTagResponse`.
|
|
1925
|
-
|
|
1926
|
-
```rust
|
|
1927
|
-
// Rust
|
|
1928
|
-
let params = BulkAddTagRequest::builder()
|
|
1929
|
-
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
|
|
1930
|
-
.label("prod".to_string())
|
|
1931
|
-
.build();
|
|
1932
|
-
let resp = qn.admin.bulk_add_tag(¶ms).await?;
|
|
1933
|
-
```
|
|
1934
|
-
|
|
1935
|
-
```python
|
|
1936
|
-
# Python
|
|
1937
|
-
resp = await qn.admin.bulk_add_tag(ids=["ep-1", "ep-2"], label="prod")
|
|
1938
|
-
```
|
|
1939
|
-
|
|
1940
|
-
```typescript
|
|
1941
|
-
// Node.js
|
|
1942
|
-
const resp = await qn.admin.bulkAddTag({ ids: ["ep-1", "ep-2"], label: "prod" });
|
|
1943
|
-
```
|
|
1944
|
-
|
|
1945
|
-
```ruby
|
|
1946
|
-
# Ruby
|
|
1947
|
-
resp = JSON.parse(qn.admin.bulk_add_tag(ids: ["ep-1", "ep-2"], label: "prod"))
|
|
1948
|
-
```
|
|
1949
|
-
|
|
1950
|
-
##### `bulk_remove_tag` / `bulkRemoveTag`
|
|
1951
|
-
|
|
1952
|
-
Removes a tag from many endpoints at once.
|
|
1953
|
-
|
|
1954
|
-
**Parameters**: `ids` (string[], required), `tag_id` (i32, required).
|
|
1955
|
-
|
|
1956
|
-
**Returns**: `BulkRemoveTagResponse`.
|
|
1957
|
-
|
|
1958
|
-
```rust
|
|
1959
|
-
// Rust
|
|
1960
|
-
let params = BulkRemoveTagRequest::builder()
|
|
1961
|
-
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
|
|
1962
|
-
.tag_id(42)
|
|
1963
|
-
.build();
|
|
1964
|
-
let resp = qn.admin.bulk_remove_tag(¶ms).await?;
|
|
1965
|
-
```
|
|
1966
|
-
|
|
1967
|
-
```python
|
|
1968
|
-
# Python
|
|
1969
|
-
resp = await qn.admin.bulk_remove_tag(ids=["ep-1", "ep-2"], tag_id=42)
|
|
1970
|
-
```
|
|
1971
|
-
|
|
1972
|
-
```typescript
|
|
1973
|
-
// Node.js
|
|
1974
|
-
const resp = await qn.admin.bulkRemoveTag({ ids: ["ep-1", "ep-2"], tagId: 42 });
|
|
1975
|
-
```
|
|
1976
|
-
|
|
1977
|
-
```ruby
|
|
1978
|
-
# Ruby
|
|
1979
|
-
resp = JSON.parse(qn.admin.bulk_remove_tag(ids: ["ep-1", "ep-2"], tag_id: 42))
|
|
1980
|
-
```
|
|
1981
|
-
|
|
1982
|
-
#### Account Tags
|
|
1983
|
-
|
|
1984
|
-
##### `list_tags` / `listTags`
|
|
1985
|
-
|
|
1986
|
-
Lists every tag on the account along with usage counts.
|
|
1987
|
-
|
|
1988
|
-
**Parameters**: none.
|
|
1989
|
-
|
|
1990
|
-
**Returns**: `ListTagsResponse` with `data.tags: AccountTag[]`.
|
|
1991
|
-
|
|
1992
|
-
```rust
|
|
1993
|
-
// Rust
|
|
1994
|
-
let resp = qn.admin.list_tags().await?;
|
|
1995
|
-
```
|
|
1996
|
-
|
|
1997
|
-
```python
|
|
1998
|
-
# Python
|
|
1999
|
-
resp = await qn.admin.list_tags()
|
|
2000
|
-
```
|
|
2001
|
-
|
|
2002
|
-
```typescript
|
|
2003
|
-
// Node.js
|
|
2004
|
-
const resp = await qn.admin.listTags();
|
|
2005
|
-
```
|
|
2006
|
-
|
|
2007
|
-
```ruby
|
|
2008
|
-
# Ruby
|
|
2009
|
-
resp = JSON.parse(qn.admin.list_tags)
|
|
2010
|
-
```
|
|
2011
|
-
|
|
2012
|
-
##### `rename_tag` / `renameTag`
|
|
2013
|
-
|
|
2014
|
-
Renames an account-level tag.
|
|
2015
|
-
|
|
2016
|
-
**Parameters**: `tag_id` (i32, required); body: `label` (string, required).
|
|
2017
|
-
|
|
2018
|
-
**Returns**: `RenameTagResponse` with updated `AccountTag`.
|
|
2019
|
-
|
|
2020
|
-
```rust
|
|
2021
|
-
// Rust
|
|
2022
|
-
let params = RenameTagRequest::builder().label("staging".to_string()).build();
|
|
2023
|
-
let resp = qn.admin.rename_tag(42, ¶ms).await?;
|
|
2024
|
-
```
|
|
2025
|
-
|
|
2026
|
-
```python
|
|
2027
|
-
# Python
|
|
2028
|
-
resp = await qn.admin.rename_tag(42, label="staging")
|
|
2029
|
-
```
|
|
2030
|
-
|
|
2031
|
-
```typescript
|
|
2032
|
-
// Node.js
|
|
2033
|
-
const resp = await qn.admin.renameTag(42, { label: "staging" });
|
|
2034
|
-
```
|
|
2035
|
-
|
|
2036
|
-
```ruby
|
|
2037
|
-
# Ruby
|
|
2038
|
-
resp = JSON.parse(qn.admin.rename_tag(tag_id: 42, label: "staging"))
|
|
2039
|
-
```
|
|
2040
|
-
|
|
2041
|
-
##### `delete_account_tag` / `deleteAccountTag`
|
|
2042
|
-
|
|
2043
|
-
Deletes a tag from the account. The tag must first be removed from any endpoints using it.
|
|
2044
|
-
|
|
2045
|
-
**Parameters**: `id` (i32, required).
|
|
2046
|
-
|
|
2047
|
-
**Returns**: `DeleteAccountTagResponse`.
|
|
2048
|
-
|
|
2049
|
-
```rust
|
|
2050
|
-
// Rust
|
|
2051
|
-
qn.admin.delete_account_tag(42).await?;
|
|
2052
|
-
```
|
|
2053
|
-
|
|
2054
|
-
```python
|
|
2055
|
-
# Python
|
|
2056
|
-
await qn.admin.delete_account_tag(42)
|
|
2057
|
-
```
|
|
2058
|
-
|
|
2059
|
-
```typescript
|
|
2060
|
-
// Node.js
|
|
2061
|
-
await qn.admin.deleteAccountTag(42);
|
|
2062
|
-
```
|
|
2063
|
-
|
|
2064
|
-
```ruby
|
|
2065
|
-
# Ruby
|
|
2066
|
-
JSON.parse(qn.admin.delete_account_tag(id: 42))
|
|
2067
|
-
```
|
|
2068
|
-
|
|
2069
|
-
---
|
|
2070
|
-
|
|
2071
|
-
### Streams Client
|
|
2072
|
-
|
|
2073
|
-
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/`.
|
|
2074
|
-
|
|
2075
|
-
#### Datasets, Regions, and Destinations
|
|
2076
|
-
|
|
2077
|
-
Enums used across stream methods:
|
|
2078
|
-
|
|
2079
|
-
- **`StreamRegion`**: `UsaEast`, `EuropeCentral`, `AsiaEast` (wire values: `usa_east`, `europe_central`, `asia_east`).
|
|
2080
|
-
- **`StreamDataset`**: `Block`, `BlockWithReceipts`, `Transactions`, `Logs`, `Receipts`, `TraceBlocks`, `DebugTraces`, `BlockWithReceiptsDebugTrace`, `BlockWithReceiptsTraceBlock`, `BlobSidecars`, `ProgramsWithLogs`, `Ledger`, `Events`, `Orders`, `Trades`, `BookUpdates`, `Twap`, `WriterActions`.
|
|
2081
|
-
- **`StreamStatus`**: `Active`, `Paused`, `Terminated`, `Completed`, `Blocked`.
|
|
2082
|
-
- **`FilterLanguage`**: `Javascript`, `Go`, `Wasm`.
|
|
2083
|
-
- **`StreamMetadataLocation`**: `Body`, `Header`, `None`.
|
|
2084
|
-
|
|
2085
|
-
Destinations are expressed via `DestinationAttributes`. Each variant wraps an attribute struct:
|
|
2086
|
-
|
|
2087
|
-
| Variant | Struct | Key fields |
|
|
2088
|
-
|---|---|---|
|
|
2089
|
-
| `Webhook` | `WebhookAttributes` | `url`, `max_retry`, `retry_interval_sec`, `post_timeout_sec`, `compression`, `security_token?` |
|
|
2090
|
-
| `S3` | `S3Attributes` | `endpoint`, `access_key`, `secret_key`, `bucket`, `object_prefix`, `compression`, `file_type`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
|
|
2091
|
-
| `Azure` | `AzureAttributes` | `storage_account`, `sas_token`, `container`, `compression`, `file_type`, `max_retry`, `retry_interval_sec`, `blob_prefix?` |
|
|
2092
|
-
| `Postgres` | `PostgresAttributes` | `host`, `port`, `username`, `password`, `database`, `schema`, `table`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
|
|
2093
|
-
| `Mysql` | `MysqlAttributes` | `host`, `port`, `username`, `password`, `database`, `table`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
|
|
2094
|
-
| `Mongo` | `MongoAttributes` | `connection_string`, `database`, `collection`, `max_retry`, `retry_interval_sec` |
|
|
2095
|
-
| `Clickhouse` | `ClickhouseAttributes` | `host`, `port`, `username`, `password`, `database`, `table`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
|
|
2096
|
-
| `Snowflake` | `SnowflakeAttributes` | `account`, `warehouse`, `database`, `schema`, `table`, `username`, `private_key`, `max_retry`, `retry_interval_sec` |
|
|
2097
|
-
| `Kafka` | `KafkaAttributes` | `bootstrap_servers`, `topic`, `compression`, `max_retry`, `retry_interval_sec` |
|
|
2098
|
-
| `Redis` | `RedisAttributes` | `host`, `port`, `username`, `password`, `key`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
|
|
2099
|
-
|
|
2100
|
-
Wrapper naming per language:
|
|
2101
|
-
|
|
2102
|
-
- **Rust**: `DestinationAttributes::Webhook(WebhookAttributes { .. })` etc.
|
|
2103
|
-
- **Python**: `StreamWebhookDestination(WebhookAttributes(...))`, `StreamS3Destination(S3Attributes(...))`, etc.
|
|
2104
|
-
- **Node.js**: a discriminated object `{ destination: "webhook", attributes: { ... } }` using string discriminators.
|
|
2105
|
-
- **Ruby**: factory methods on `QuickNodeSdk::DestinationAttributes`, e.g. `QuickNodeSdk::DestinationAttributes.webhook(url: ..., ...)`.
|
|
2106
|
-
|
|
2107
|
-
#### Streams methods
|
|
2108
|
-
|
|
2109
|
-
##### `create_stream` / `createStream`
|
|
2110
|
-
|
|
2111
|
-
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.
|
|
2112
|
-
|
|
2113
|
-
**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`.
|
|
2114
|
-
|
|
2115
|
-
**Returns**: `Stream`.
|
|
2116
|
-
|
|
2117
|
-
```rust
|
|
2118
|
-
// Rust
|
|
2119
|
-
let params = CreateStreamParams::builder()
|
|
2120
|
-
.name("My Stream".to_string())
|
|
2121
|
-
.region(StreamRegion::UsaEast)
|
|
2122
|
-
.network("ethereum-mainnet".to_string())
|
|
2123
|
-
.dataset(StreamDataset::Block)
|
|
2124
|
-
.start_range(24691804)
|
|
2125
|
-
.end_range(24691904)
|
|
2126
|
-
.destination_attributes(DestinationAttributes::Webhook(WebhookAttributes {
|
|
2127
|
-
url: "https://webhook.site/...".to_string(),
|
|
2128
|
-
max_retry: 3,
|
|
2129
|
-
retry_interval_sec: 1,
|
|
2130
|
-
post_timeout_sec: 10,
|
|
2131
|
-
compression: "none".to_string(),
|
|
2132
|
-
security_token: None,
|
|
2133
|
-
}))
|
|
2134
|
-
.plan("growth_plan".to_string())
|
|
2135
|
-
.threshold_fetch_buffer(1000)
|
|
2136
|
-
.status(StreamStatus::Active)
|
|
2137
|
-
.build();
|
|
2138
|
-
let stream = qn.streams.create_stream(¶ms).await?;
|
|
2139
|
-
```
|
|
2140
|
-
|
|
2141
|
-
```python
|
|
2142
|
-
# Python
|
|
2143
|
-
from sdk import WebhookAttributes, StreamWebhookDestination
|
|
2144
|
-
|
|
2145
|
-
stream = await qn.streams.create_stream(
|
|
2146
|
-
name="My Stream",
|
|
2147
|
-
network="ethereum-mainnet",
|
|
2148
|
-
dataset="block",
|
|
2149
|
-
region="usa_east",
|
|
2150
|
-
start_range=24691804,
|
|
2151
|
-
end_range=24691904,
|
|
2152
|
-
destination_attributes=StreamWebhookDestination(
|
|
2153
|
-
WebhookAttributes(
|
|
2154
|
-
url="https://webhook.site/...",
|
|
2155
|
-
max_retry=3,
|
|
2156
|
-
retry_interval_sec=1,
|
|
2157
|
-
post_timeout_sec=10,
|
|
2158
|
-
compression="none",
|
|
2159
|
-
)
|
|
2160
|
-
),
|
|
2161
|
-
plan="growth_plan",
|
|
2162
|
-
threshold_fetch_buffer=1000,
|
|
2163
|
-
status="active",
|
|
2164
|
-
)
|
|
2165
|
-
```
|
|
2166
|
-
|
|
2167
|
-
```typescript
|
|
2168
|
-
// Node.js
|
|
2169
|
-
import { StreamDataset, StreamRegion, StreamStatus } from "quicknode-sdk";
|
|
2170
|
-
|
|
2171
|
-
const stream = await qn.streams.createStream({
|
|
2172
|
-
name: "My Stream",
|
|
2173
|
-
network: "ethereum-mainnet",
|
|
2174
|
-
dataset: StreamDataset.Block,
|
|
2175
|
-
region: StreamRegion.UsaEast,
|
|
2176
|
-
startRange: 24691804,
|
|
2177
|
-
endRange: 24691904,
|
|
2178
|
-
destinationAttributes: {
|
|
2179
|
-
destination: "webhook",
|
|
2180
|
-
attributes: {
|
|
2181
|
-
url: "https://webhook.site/...",
|
|
2182
|
-
maxRetry: 3,
|
|
2183
|
-
retryIntervalSec: 1,
|
|
2184
|
-
postTimeoutSec: 10,
|
|
2185
|
-
compression: "none",
|
|
2186
|
-
},
|
|
2187
|
-
},
|
|
2188
|
-
plan: "growth_plan",
|
|
2189
|
-
thresholdFetchBuffer: 1000,
|
|
2190
|
-
status: StreamStatus.Active,
|
|
2191
|
-
});
|
|
2192
|
-
```
|
|
2193
|
-
|
|
2194
|
-
```ruby
|
|
2195
|
-
# Ruby
|
|
2196
|
-
dest = QuickNodeSdk::DestinationAttributes.webhook(
|
|
2197
|
-
url: "https://webhook.site/...",
|
|
2198
|
-
max_retry: 3,
|
|
2199
|
-
retry_interval_sec: 1,
|
|
2200
|
-
post_timeout_sec: 10,
|
|
2201
|
-
compression: "none"
|
|
2202
|
-
)
|
|
2203
|
-
stream = JSON.parse(qn.streams.create_stream(
|
|
2204
|
-
name: "My Stream",
|
|
2205
|
-
network: "ethereum-mainnet",
|
|
2206
|
-
dataset: "block",
|
|
2207
|
-
region: "usa_east",
|
|
2208
|
-
start_range: 24691804,
|
|
2209
|
-
end_range: 24691904,
|
|
2210
|
-
destination_attributes: dest,
|
|
2211
|
-
plan: "growth_plan",
|
|
2212
|
-
threshold_fetch_buffer: 1000,
|
|
2213
|
-
status: "active"
|
|
2214
|
-
))
|
|
2215
|
-
```
|
|
2216
|
-
|
|
2217
|
-
##### `list_streams` / `listStreams`
|
|
2218
|
-
|
|
2219
|
-
Paginated list of streams on the account.
|
|
2220
|
-
|
|
2221
|
-
**Parameters** (all optional): `offset` (i64), `limit` (i64), `order_by` (string), `order_direction` (`"asc"` | `"desc"`), `stream_type` (string).
|
|
2222
|
-
|
|
2223
|
-
**Returns**: `ListStreamsResponse` with `data: Stream[]` and `page_info`.
|
|
2224
|
-
|
|
2225
|
-
```rust
|
|
2226
|
-
// Rust
|
|
2227
|
-
let resp = qn.streams.list_streams(&ListStreamsParams::default()).await?;
|
|
2228
|
-
```
|
|
2229
|
-
|
|
2230
|
-
```python
|
|
2231
|
-
# Python
|
|
2232
|
-
resp = await qn.streams.list_streams()
|
|
2233
|
-
```
|
|
2234
|
-
|
|
2235
|
-
```typescript
|
|
2236
|
-
// Node.js
|
|
2237
|
-
const resp = await qn.streams.listStreams();
|
|
2238
|
-
```
|
|
2239
|
-
|
|
2240
|
-
```ruby
|
|
2241
|
-
# Ruby
|
|
2242
|
-
resp = JSON.parse(qn.streams.list_streams({}))
|
|
2243
|
-
```
|
|
2244
|
-
|
|
2245
|
-
##### `get_stream` / `getStream`
|
|
2246
|
-
|
|
2247
|
-
Fetches one stream by id.
|
|
2248
|
-
|
|
2249
|
-
**Parameters**: `id` (string, required).
|
|
2250
|
-
|
|
2251
|
-
**Returns**: `Stream`.
|
|
2252
|
-
|
|
2253
|
-
```rust
|
|
2254
|
-
// Rust
|
|
2255
|
-
let stream = qn.streams.get_stream("stream-id").await?;
|
|
2256
|
-
```
|
|
2257
|
-
|
|
2258
|
-
```python
|
|
2259
|
-
# Python
|
|
2260
|
-
stream = await qn.streams.get_stream("stream-id")
|
|
2261
|
-
```
|
|
2262
|
-
|
|
2263
|
-
```typescript
|
|
2264
|
-
// Node.js
|
|
2265
|
-
const stream = await qn.streams.getStream("stream-id");
|
|
2266
|
-
```
|
|
2267
|
-
|
|
2268
|
-
```ruby
|
|
2269
|
-
# Ruby
|
|
2270
|
-
stream = JSON.parse(qn.streams.get_stream(id: "stream-id"))
|
|
2271
|
-
```
|
|
2272
|
-
|
|
2273
|
-
##### `update_stream` / `updateStream`
|
|
2274
|
-
|
|
2275
|
-
Partially updates a stream. Omitted fields are left unchanged.
|
|
2276
|
-
|
|
2277
|
-
**Parameters**: `id` (string, required); body: any field from `CreateStreamParams` (all optional).
|
|
2278
|
-
|
|
2279
|
-
**Returns**: updated `Stream`.
|
|
2280
|
-
|
|
2281
|
-
```rust
|
|
2282
|
-
// Rust
|
|
2283
|
-
let params = UpdateStreamParams {
|
|
2284
|
-
name: Some("Renamed".to_string()),
|
|
2285
|
-
..Default::default()
|
|
2286
|
-
};
|
|
2287
|
-
let stream = qn.streams.update_stream("stream-id", ¶ms).await?;
|
|
2288
|
-
```
|
|
2289
|
-
|
|
2290
|
-
```python
|
|
2291
|
-
# Python
|
|
2292
|
-
stream = await qn.streams.update_stream("stream-id", name="Renamed")
|
|
2293
|
-
```
|
|
2294
|
-
|
|
2295
|
-
```typescript
|
|
2296
|
-
// Node.js
|
|
2297
|
-
const stream = await qn.streams.updateStream("stream-id", { name: "Renamed" });
|
|
2298
|
-
```
|
|
2299
|
-
|
|
2300
|
-
```ruby
|
|
2301
|
-
# Ruby
|
|
2302
|
-
stream = JSON.parse(qn.streams.update_stream(id: "stream-id", name: "Renamed"))
|
|
2303
|
-
```
|
|
2304
|
-
|
|
2305
|
-
##### `delete_stream` / `deleteStream`
|
|
2306
|
-
|
|
2307
|
-
Deletes one stream by id.
|
|
2308
|
-
|
|
2309
|
-
**Parameters**: `id` (string, required).
|
|
2310
|
-
|
|
2311
|
-
**Returns**: nothing.
|
|
2312
|
-
|
|
2313
|
-
```rust
|
|
2314
|
-
// Rust
|
|
2315
|
-
qn.streams.delete_stream("stream-id").await?;
|
|
2316
|
-
```
|
|
2317
|
-
|
|
2318
|
-
```python
|
|
2319
|
-
# Python
|
|
2320
|
-
await qn.streams.delete_stream("stream-id")
|
|
2321
|
-
```
|
|
2322
|
-
|
|
2323
|
-
```typescript
|
|
2324
|
-
// Node.js
|
|
2325
|
-
await qn.streams.deleteStream("stream-id");
|
|
2326
|
-
```
|
|
2327
|
-
|
|
2328
|
-
```ruby
|
|
2329
|
-
# Ruby
|
|
2330
|
-
qn.streams.delete_stream(id: "stream-id")
|
|
2331
|
-
```
|
|
2332
|
-
|
|
2333
|
-
##### `delete_all_streams` / `deleteAllStreams`
|
|
2334
|
-
|
|
2335
|
-
Deletes every stream on the account. Destructive and takes no arguments.
|
|
2336
|
-
|
|
2337
|
-
**Parameters**: none.
|
|
2338
|
-
|
|
2339
|
-
**Returns**: nothing.
|
|
2340
|
-
|
|
2341
|
-
```rust
|
|
2342
|
-
// Rust
|
|
2343
|
-
qn.streams.delete_all_streams().await?;
|
|
2344
|
-
```
|
|
2345
|
-
|
|
2346
|
-
```python
|
|
2347
|
-
# Python
|
|
2348
|
-
await qn.streams.delete_all_streams()
|
|
2349
|
-
```
|
|
2350
|
-
|
|
2351
|
-
```typescript
|
|
2352
|
-
// Node.js
|
|
2353
|
-
await qn.streams.deleteAllStreams();
|
|
2354
|
-
```
|
|
2355
|
-
|
|
2356
|
-
```ruby
|
|
2357
|
-
# Ruby
|
|
2358
|
-
qn.streams.delete_all_streams
|
|
2359
|
-
```
|
|
2360
|
-
|
|
2361
|
-
##### `activate_stream` / `activateStream`
|
|
2362
|
-
|
|
2363
|
-
Resumes delivery on a stream from its current position.
|
|
2364
|
-
|
|
2365
|
-
**Parameters**: `id` (string, required).
|
|
2366
|
-
|
|
2367
|
-
**Returns**: nothing.
|
|
2368
|
-
|
|
2369
|
-
```rust
|
|
2370
|
-
// Rust
|
|
2371
|
-
qn.streams.activate_stream("stream-id").await?;
|
|
2372
|
-
```
|
|
2373
|
-
|
|
2374
|
-
```python
|
|
2375
|
-
# Python
|
|
2376
|
-
await qn.streams.activate_stream("stream-id")
|
|
2377
|
-
```
|
|
2378
|
-
|
|
2379
|
-
```typescript
|
|
2380
|
-
// Node.js
|
|
2381
|
-
await qn.streams.activateStream("stream-id");
|
|
2382
|
-
```
|
|
2383
|
-
|
|
2384
|
-
```ruby
|
|
2385
|
-
# Ruby
|
|
2386
|
-
qn.streams.activate_stream(id: "stream-id")
|
|
2387
|
-
```
|
|
2388
|
-
|
|
2389
|
-
##### `pause_stream` / `pauseStream`
|
|
2390
|
-
|
|
2391
|
-
Halts delivery on a stream.
|
|
2392
|
-
|
|
2393
|
-
**Parameters**: `id` (string, required).
|
|
2394
|
-
|
|
2395
|
-
**Returns**: nothing.
|
|
2396
|
-
|
|
2397
|
-
```rust
|
|
2398
|
-
// Rust
|
|
2399
|
-
qn.streams.pause_stream("stream-id").await?;
|
|
2400
|
-
```
|
|
2401
|
-
|
|
2402
|
-
```python
|
|
2403
|
-
# Python
|
|
2404
|
-
await qn.streams.pause_stream("stream-id")
|
|
2405
|
-
```
|
|
2406
|
-
|
|
2407
|
-
```typescript
|
|
2408
|
-
// Node.js
|
|
2409
|
-
await qn.streams.pauseStream("stream-id");
|
|
2410
|
-
```
|
|
2411
|
-
|
|
2412
|
-
```ruby
|
|
2413
|
-
# Ruby
|
|
2414
|
-
qn.streams.pause_stream(id: "stream-id")
|
|
2415
|
-
```
|
|
2416
|
-
|
|
2417
|
-
##### `test_filter` / `testFilter`
|
|
2418
|
-
|
|
2419
|
-
Runs a filter function against a block so it can be validated before being attached to a live stream.
|
|
2420
|
-
|
|
2421
|
-
**Parameters**: `network` (string, required), `dataset` (`StreamDataset`, required), `block` (string, required), `filter_function` (string, optional), `filter_language` (`FilterLanguage`, optional), `address_book_config` (optional).
|
|
2422
|
-
|
|
2423
|
-
**Returns**: `TestFilterResponse` with `result` and `logs`.
|
|
2424
|
-
|
|
2425
|
-
```rust
|
|
2426
|
-
// Rust
|
|
2427
|
-
let params = TestFilterParams {
|
|
2428
|
-
network: "ethereum-mainnet".to_string(),
|
|
2429
|
-
dataset: StreamDataset::Block,
|
|
2430
|
-
block: "17811625".to_string(),
|
|
2431
|
-
filter_function: None,
|
|
2432
|
-
filter_language: None,
|
|
2433
|
-
address_book_config: None,
|
|
2434
|
-
};
|
|
2435
|
-
let resp = qn.streams.test_filter(¶ms).await?;
|
|
2436
|
-
```
|
|
2437
|
-
|
|
2438
|
-
```python
|
|
2439
|
-
# Python
|
|
2440
|
-
resp = await qn.streams.test_filter(
|
|
2441
|
-
network="ethereum-mainnet",
|
|
2442
|
-
dataset="block",
|
|
2443
|
-
block="17811625",
|
|
2444
|
-
)
|
|
2445
|
-
```
|
|
2446
|
-
|
|
2447
|
-
```typescript
|
|
2448
|
-
// Node.js
|
|
2449
|
-
import { StreamDataset } from "quicknode-sdk";
|
|
2450
|
-
|
|
2451
|
-
const resp = await qn.streams.testFilter({
|
|
2452
|
-
network: "ethereum-mainnet",
|
|
2453
|
-
dataset: StreamDataset.Block,
|
|
2454
|
-
block: "17811625",
|
|
2455
|
-
});
|
|
2456
|
-
```
|
|
2457
|
-
|
|
2458
|
-
```ruby
|
|
2459
|
-
# Ruby
|
|
2460
|
-
resp = JSON.parse(qn.streams.test_filter(
|
|
2461
|
-
network: "ethereum-mainnet",
|
|
2462
|
-
dataset: "block",
|
|
2463
|
-
block: "17811625"
|
|
2464
|
-
))
|
|
2465
|
-
```
|
|
2466
|
-
|
|
2467
|
-
##### `get_enabled_count` / `getEnabledCount`
|
|
2468
|
-
|
|
2469
|
-
Counts currently enabled (active) streams, optionally filtered by type.
|
|
2470
|
-
|
|
2471
|
-
**Parameters**: `stream_type` (string, optional).
|
|
2472
|
-
|
|
2473
|
-
**Returns**: `EnabledCountResponse` with `total`.
|
|
2474
|
-
|
|
2475
|
-
```rust
|
|
2476
|
-
// Rust
|
|
2477
|
-
let resp = qn.streams.get_enabled_count(None).await?;
|
|
2478
|
-
```
|
|
2479
|
-
|
|
2480
|
-
```python
|
|
2481
|
-
# Python
|
|
2482
|
-
resp = await qn.streams.get_enabled_count()
|
|
2483
|
-
```
|
|
2484
|
-
|
|
2485
|
-
```typescript
|
|
2486
|
-
// Node.js
|
|
2487
|
-
const resp = await qn.streams.getEnabledCount();
|
|
2488
|
-
```
|
|
2489
|
-
|
|
2490
|
-
```ruby
|
|
2491
|
-
# Ruby
|
|
2492
|
-
resp = JSON.parse(qn.streams.get_enabled_count({}))
|
|
2493
|
-
```
|
|
2494
|
-
|
|
2495
|
-
---
|
|
2496
|
-
|
|
2497
|
-
### Webhooks Client
|
|
2498
|
-
|
|
2499
|
-
Accessed as `qn.webhooks`. Creates webhooks from filter templates and manages their lifecycle. Backed by `https://api.quicknode.com/webhooks/rest/v1/`.
|
|
2500
|
-
|
|
2501
|
-
#### Templates and destination
|
|
2502
|
-
|
|
2503
|
-
`WebhookTemplateId` identifies the filter template:
|
|
2504
|
-
|
|
2505
|
-
| Variant | Wire value |
|
|
2506
|
-
|---|---|
|
|
2507
|
-
| `EvmWalletFilter` | `evmWalletFilter` |
|
|
2508
|
-
| `EvmContractEvents` | `evmContractEvents` |
|
|
2509
|
-
| `EvmAbiFilter` | `evmAbiFilter` |
|
|
2510
|
-
| `SolanaWalletFilter` | `solanaWalletFilter` |
|
|
2511
|
-
| `BitcoinWalletFilter` | `bitcoinWalletFilter` |
|
|
2512
|
-
| `XrplWalletFilter` | `xrplWalletFilter` |
|
|
2513
|
-
| `HyperliquidWalletEventsFilter` | `hyperliquidWalletEventsFilter` |
|
|
2514
|
-
| `StellarWalletTransactionsSourceAccountFilter` | `stellarWalletTransactionsSourceAccountFilter` |
|
|
2515
|
-
|
|
2516
|
-
`TemplateArgs` carries the arguments; construct one per template via the factory methods:
|
|
2517
|
-
|
|
2518
|
-
| Factory | Argument struct | Fields |
|
|
2519
|
-
|---|---|---|
|
|
2520
|
-
| `evm_wallet_filter` | `EvmWalletFilterTemplate` | `wallets: string[]` |
|
|
2521
|
-
| `evm_contract_events` | `EvmContractEventsTemplate` | `contracts: string[]`, `event_hashes?: string[]` |
|
|
2522
|
-
| `evm_abi_filter` | `EvmAbiFilterTemplate` | `abi: string` (JSON), `contracts: string[]` |
|
|
2523
|
-
| `solana_wallet_filter` | `SolanaWalletFilterTemplate` | `accounts: string[]` |
|
|
2524
|
-
| `bitcoin_wallet_filter` | `BitcoinWalletFilterTemplate` | `wallets: string[]` |
|
|
2525
|
-
| `xrpl_wallet_filter` | `XrplWalletFilterTemplate` | `wallets: string[]` |
|
|
2526
|
-
| `hyperliquid_wallet_events_filter` | `HyperliquidWalletEventsFilterTemplate` | `wallets: string[]` |
|
|
2527
|
-
| `stellar_wallet_transactions_filter` | `StellarWalletTransactionsFilterTemplate` | `source_accounts: string[]` |
|
|
2528
|
-
|
|
2529
|
-
`WebhookDestinationAttributes`: `url` (required), `security_token` (optional — auto-generated if omitted), `compression` (optional — `"none"` | `"gzip"`).
|
|
2530
|
-
|
|
2531
|
-
`WebhookStartFrom`: `Last` (resume from last delivered block) or `Latest` (start from newest).
|
|
2532
|
-
|
|
2533
|
-
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`.
|
|
2534
|
-
|
|
2535
|
-
#### Webhooks methods
|
|
2536
|
-
|
|
2537
|
-
##### `list_webhooks` / `listWebhooks`
|
|
2538
|
-
|
|
2539
|
-
Paginated list of webhooks.
|
|
2540
|
-
|
|
2541
|
-
**Parameters** (all optional): `limit` (i64), `offset` (i64).
|
|
2542
|
-
|
|
2543
|
-
**Returns**: `ListWebhooksResponse` with `data: Webhook[]` and `pageInfo`.
|
|
2544
|
-
|
|
2545
|
-
```rust
|
|
2546
|
-
// Rust
|
|
2547
|
-
let resp = qn.webhooks.list_webhooks(&GetWebhooksParams::default()).await?;
|
|
2548
|
-
```
|
|
2549
|
-
|
|
2550
|
-
```python
|
|
2551
|
-
# Python
|
|
2552
|
-
resp = await qn.webhooks.list_webhooks()
|
|
2553
|
-
```
|
|
2554
|
-
|
|
2555
|
-
```typescript
|
|
2556
|
-
// Node.js
|
|
2557
|
-
const resp = await qn.webhooks.listWebhooks();
|
|
2558
|
-
```
|
|
2559
|
-
|
|
2560
|
-
```ruby
|
|
2561
|
-
# Ruby
|
|
2562
|
-
resp = JSON.parse(qn.webhooks.list_webhooks({}))
|
|
2563
|
-
```
|
|
2564
|
-
|
|
2565
|
-
##### `get_webhook` / `getWebhook`
|
|
2566
|
-
|
|
2567
|
-
Fetches a webhook by id.
|
|
2568
|
-
|
|
2569
|
-
**Parameters**: `id` (string, required).
|
|
2570
|
-
|
|
2571
|
-
**Returns**: `Webhook`.
|
|
2572
|
-
|
|
2573
|
-
```rust
|
|
2574
|
-
// Rust
|
|
2575
|
-
let webhook = qn.webhooks.get_webhook("wh-1").await?;
|
|
2576
|
-
```
|
|
2577
|
-
|
|
2578
|
-
```python
|
|
2579
|
-
# Python
|
|
2580
|
-
webhook = await qn.webhooks.get_webhook("wh-1")
|
|
2581
|
-
```
|
|
2582
|
-
|
|
2583
|
-
```typescript
|
|
2584
|
-
// Node.js
|
|
2585
|
-
const webhook = await qn.webhooks.getWebhook("wh-1");
|
|
2586
|
-
```
|
|
2587
|
-
|
|
2588
|
-
```ruby
|
|
2589
|
-
# Ruby
|
|
2590
|
-
webhook = JSON.parse(qn.webhooks.get_webhook(id: "wh-1"))
|
|
2591
|
-
```
|
|
2592
|
-
|
|
2593
|
-
##### `create_webhook_from_template` / `createWebhookFromTemplate`
|
|
2594
|
-
|
|
2595
|
-
Creates a webhook from a predefined filter template.
|
|
2596
|
-
|
|
2597
|
-
**Parameters**: `name` (required), `network` (required), `destination_attributes` (`WebhookDestinationAttributes`, required), `template_args` (`TemplateArgs`, required), `notification_email` (optional).
|
|
2598
|
-
|
|
2599
|
-
**Returns**: `Webhook`.
|
|
2600
|
-
|
|
2601
|
-
```rust
|
|
2602
|
-
// Rust
|
|
2603
|
-
let template_args = TemplateArgs::evm_wallet_filter(&EvmWalletFilterTemplate {
|
|
2604
|
-
wallets: vec!["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48".to_string()],
|
|
2605
|
-
})?;
|
|
2606
|
-
let params = CreateWebhookFromTemplateParams {
|
|
2607
|
-
name: "Wallet Webhook".to_string(),
|
|
2608
|
-
network: "ethereum-mainnet".to_string(),
|
|
2609
|
-
notification_email: None,
|
|
2610
|
-
destination_attributes: WebhookDestinationAttributes {
|
|
2611
|
-
url: "https://webhook.site/...".to_string(),
|
|
2612
|
-
security_token: None,
|
|
2613
|
-
compression: None,
|
|
2614
|
-
},
|
|
2615
|
-
template_args,
|
|
2616
|
-
};
|
|
2617
|
-
let webhook = qn.webhooks.create_webhook_from_template(¶ms).await?;
|
|
2618
|
-
```
|
|
2619
|
-
|
|
2620
|
-
```python
|
|
2621
|
-
# Python
|
|
2622
|
-
from sdk import EvmWalletFilterTemplate, TemplateArgs, WebhookDestinationAttributes
|
|
2623
|
-
|
|
2624
|
-
webhook = await qn.webhooks.create_webhook_from_template(
|
|
2625
|
-
name="Wallet Webhook",
|
|
2626
|
-
network="ethereum-mainnet",
|
|
2627
|
-
destination_attributes=WebhookDestinationAttributes(url="https://webhook.site/..."),
|
|
2628
|
-
template_args=TemplateArgs.evm_wallet_filter(
|
|
2629
|
-
EvmWalletFilterTemplate(wallets=["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"])
|
|
2630
|
-
),
|
|
2631
|
-
)
|
|
2632
|
-
```
|
|
2633
|
-
|
|
2634
|
-
```typescript
|
|
2635
|
-
// Node.js
|
|
2636
|
-
import { TemplateArgs } from "quicknode-sdk";
|
|
2637
|
-
|
|
2638
|
-
const webhook = await qn.webhooks.createWebhookFromTemplate({
|
|
2639
|
-
name: "Wallet Webhook",
|
|
2640
|
-
network: "ethereum-mainnet",
|
|
2641
|
-
destinationAttributes: { url: "https://webhook.site/..." },
|
|
2642
|
-
templateArgs: TemplateArgs.evmWalletFilter({
|
|
2643
|
-
wallets: ["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"],
|
|
2644
|
-
}),
|
|
2645
|
-
});
|
|
2646
|
-
```
|
|
2647
|
-
|
|
2648
|
-
```ruby
|
|
2649
|
-
# Ruby
|
|
2650
|
-
destination_attributes = JSON.generate({
|
|
2651
|
-
url: "https://webhook.site/...",
|
|
2652
|
-
compression: "none"
|
|
2653
|
-
})
|
|
2654
|
-
template_args = JSON.generate({
|
|
2655
|
-
template_id: "evmWalletFilter",
|
|
2656
|
-
value: JSON.generate({ wallets: ["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"] })
|
|
2657
|
-
})
|
|
2658
|
-
webhook = JSON.parse(qn.webhooks.create_webhook_from_template(
|
|
2659
|
-
name: "Wallet Webhook",
|
|
2660
|
-
network: "ethereum-mainnet",
|
|
2661
|
-
destination_attributes_json: destination_attributes,
|
|
2662
|
-
template_args_json: template_args
|
|
2663
|
-
))
|
|
2664
|
-
```
|
|
2665
|
-
|
|
2666
|
-
##### `update_webhook` / `updateWebhook`
|
|
2667
|
-
|
|
2668
|
-
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.
|
|
2669
|
-
|
|
2670
|
-
**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`.
|
|
2671
|
-
|
|
2672
|
-
**Returns**: updated `Webhook`.
|
|
2673
|
-
|
|
2674
|
-
```rust
|
|
2675
|
-
// Rust
|
|
2676
|
-
let params = UpdateWebhookParams {
|
|
2677
|
-
name: Some("Renamed Webhook".to_string()),
|
|
2678
|
-
..Default::default()
|
|
2679
|
-
};
|
|
2680
|
-
let webhook = qn.webhooks.update_webhook("wh-1", ¶ms).await?;
|
|
2681
|
-
```
|
|
2682
|
-
|
|
2683
|
-
```python
|
|
2684
|
-
# Python
|
|
2685
|
-
webhook = await qn.webhooks.update_webhook("wh-1", name="Renamed Webhook")
|
|
2686
|
-
```
|
|
2687
|
-
|
|
2688
|
-
```typescript
|
|
2689
|
-
// Node.js
|
|
2690
|
-
const webhook = await qn.webhooks.updateWebhook("wh-1", { name: "Renamed Webhook" });
|
|
2691
|
-
```
|
|
2692
|
-
|
|
2693
|
-
```ruby
|
|
2694
|
-
# Ruby
|
|
2695
|
-
webhook = JSON.parse(qn.webhooks.update_webhook(id: "wh-1", name: "Renamed Webhook"))
|
|
2696
|
-
```
|
|
2697
|
-
|
|
2698
|
-
##### `update_webhook_template` / `updateWebhookTemplate`
|
|
2699
|
-
|
|
2700
|
-
Updates the template args (and optionally name, email, destination) on an existing template-backed webhook.
|
|
2701
|
-
|
|
2702
|
-
**Parameters**: `webhook_id` (required), `template_args` (required); optional: `name`, `notification_email`, `destination_attributes`.
|
|
2703
|
-
|
|
2704
|
-
**Returns**: updated `Webhook`.
|
|
2705
|
-
|
|
2706
|
-
```rust
|
|
2707
|
-
// Rust
|
|
2708
|
-
let template_args = TemplateArgs::evm_wallet_filter(&EvmWalletFilterTemplate {
|
|
2709
|
-
wallets: vec!["0xnewwallet".to_string()],
|
|
2710
|
-
})?;
|
|
2711
|
-
let params = UpdateWebhookTemplateParams {
|
|
2712
|
-
name: None,
|
|
2713
|
-
notification_email: None,
|
|
2714
|
-
destination_attributes: None,
|
|
2715
|
-
template_args,
|
|
2716
|
-
};
|
|
2717
|
-
let webhook = qn.webhooks.update_webhook_template("wh-1", ¶ms).await?;
|
|
2718
|
-
```
|
|
2719
|
-
|
|
2720
|
-
```python
|
|
2721
|
-
# Python
|
|
2722
|
-
webhook = await qn.webhooks.update_webhook_template(
|
|
2723
|
-
"wh-1",
|
|
2724
|
-
template_args=TemplateArgs.evm_wallet_filter(
|
|
2725
|
-
EvmWalletFilterTemplate(wallets=["0xnewwallet"])
|
|
2726
|
-
),
|
|
2727
|
-
)
|
|
2728
|
-
```
|
|
2729
|
-
|
|
2730
|
-
```typescript
|
|
2731
|
-
// Node.js
|
|
2732
|
-
const webhook = await qn.webhooks.updateWebhookTemplate("wh-1", {
|
|
2733
|
-
templateArgs: TemplateArgs.evmWalletFilter({ wallets: ["0xnewwallet"] }),
|
|
2734
|
-
});
|
|
2735
|
-
```
|
|
2736
|
-
|
|
2737
|
-
```ruby
|
|
2738
|
-
# Ruby
|
|
2739
|
-
template_args = JSON.generate({
|
|
2740
|
-
template_id: "evmWalletFilter",
|
|
2741
|
-
value: JSON.generate({ wallets: ["0xnewwallet"] })
|
|
2742
|
-
})
|
|
2743
|
-
webhook = JSON.parse(qn.webhooks.update_webhook_template(
|
|
2744
|
-
webhook_id: "wh-1",
|
|
2745
|
-
template_args_json: template_args
|
|
2746
|
-
))
|
|
2747
|
-
```
|
|
2748
|
-
|
|
2749
|
-
##### `delete_webhook` / `deleteWebhook`
|
|
2750
|
-
|
|
2751
|
-
Deletes a webhook.
|
|
2752
|
-
|
|
2753
|
-
**Parameters**: `id` (required).
|
|
2754
|
-
|
|
2755
|
-
**Returns**: nothing.
|
|
2756
|
-
|
|
2757
|
-
```rust
|
|
2758
|
-
// Rust
|
|
2759
|
-
qn.webhooks.delete_webhook("wh-1").await?;
|
|
2760
|
-
```
|
|
2761
|
-
|
|
2762
|
-
```python
|
|
2763
|
-
# Python
|
|
2764
|
-
await qn.webhooks.delete_webhook("wh-1")
|
|
2765
|
-
```
|
|
2766
|
-
|
|
2767
|
-
```typescript
|
|
2768
|
-
// Node.js
|
|
2769
|
-
await qn.webhooks.deleteWebhook("wh-1");
|
|
2770
|
-
```
|
|
2771
|
-
|
|
2772
|
-
```ruby
|
|
2773
|
-
# Ruby
|
|
2774
|
-
qn.webhooks.delete_webhook(id: "wh-1")
|
|
2775
|
-
```
|
|
2776
|
-
|
|
2777
|
-
##### `delete_all_webhooks` / `deleteAllWebhooks`
|
|
2778
|
-
|
|
2779
|
-
Deletes every webhook on the account. Destructive and takes no arguments.
|
|
2780
|
-
|
|
2781
|
-
**Parameters**: none.
|
|
2782
|
-
|
|
2783
|
-
**Returns**: nothing.
|
|
2784
|
-
|
|
2785
|
-
```rust
|
|
2786
|
-
// Rust
|
|
2787
|
-
qn.webhooks.delete_all_webhooks().await?;
|
|
2788
|
-
```
|
|
2789
|
-
|
|
2790
|
-
```python
|
|
2791
|
-
# Python
|
|
2792
|
-
await qn.webhooks.delete_all_webhooks()
|
|
2793
|
-
```
|
|
2794
|
-
|
|
2795
|
-
```typescript
|
|
2796
|
-
// Node.js
|
|
2797
|
-
await qn.webhooks.deleteAllWebhooks();
|
|
2798
|
-
```
|
|
2799
|
-
|
|
2800
|
-
```ruby
|
|
2801
|
-
# Ruby
|
|
2802
|
-
qn.webhooks.delete_all_webhooks
|
|
2803
|
-
```
|
|
2804
|
-
|
|
2805
|
-
##### `pause_webhook` / `pauseWebhook`
|
|
2806
|
-
|
|
2807
|
-
Pauses a webhook so it stops delivering events.
|
|
2808
|
-
|
|
2809
|
-
**Parameters**: `id` (required).
|
|
2810
|
-
|
|
2811
|
-
**Returns**: nothing.
|
|
2812
|
-
|
|
2813
|
-
```rust
|
|
2814
|
-
// Rust
|
|
2815
|
-
qn.webhooks.pause_webhook("wh-1").await?;
|
|
2816
|
-
```
|
|
2817
|
-
|
|
2818
|
-
```python
|
|
2819
|
-
# Python
|
|
2820
|
-
await qn.webhooks.pause_webhook("wh-1")
|
|
2821
|
-
```
|
|
2822
|
-
|
|
2823
|
-
```typescript
|
|
2824
|
-
// Node.js
|
|
2825
|
-
await qn.webhooks.pauseWebhook("wh-1");
|
|
2826
|
-
```
|
|
2827
|
-
|
|
2828
|
-
```ruby
|
|
2829
|
-
# Ruby
|
|
2830
|
-
qn.webhooks.pause_webhook(id: "wh-1")
|
|
2831
|
-
```
|
|
2832
|
-
|
|
2833
|
-
##### `activate_webhook` / `activateWebhook`
|
|
2834
|
-
|
|
2835
|
-
Activates a paused or new webhook so it resumes delivering events. `start_from` determines where processing resumes.
|
|
2836
|
-
|
|
2837
|
-
**Parameters**: `id` (required), `start_from` (`WebhookStartFrom`, required — `Last` or `Latest`).
|
|
24
|
+
## Per-language docs
|
|
2838
25
|
|
|
2839
|
-
|
|
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.
|
|
2840
27
|
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
```
|
|
2846
|
-
|
|
2847
|
-
```python
|
|
2848
|
-
# Python
|
|
2849
|
-
await qn.webhooks.activate_webhook("wh-1", start_from="latest")
|
|
2850
|
-
```
|
|
2851
|
-
|
|
2852
|
-
```typescript
|
|
2853
|
-
// Node.js
|
|
2854
|
-
import { WebhookStartFrom } from "quicknode-sdk";
|
|
2855
|
-
|
|
2856
|
-
await qn.webhooks.activateWebhook("wh-1", { startFrom: WebhookStartFrom.Latest });
|
|
2857
|
-
```
|
|
2858
|
-
|
|
2859
|
-
```ruby
|
|
2860
|
-
# Ruby
|
|
2861
|
-
qn.webhooks.activate_webhook(id: "wh-1", start_from: "latest")
|
|
2862
|
-
```
|
|
2863
|
-
|
|
2864
|
-
##### `get_enabled_count` / `getEnabledCount`
|
|
2865
|
-
|
|
2866
|
-
Counts currently enabled webhooks.
|
|
2867
|
-
|
|
2868
|
-
**Parameters**: none.
|
|
2869
|
-
|
|
2870
|
-
**Returns**: `WebhookEnabledCountResponse` with `total`.
|
|
2871
|
-
|
|
2872
|
-
```rust
|
|
2873
|
-
// Rust
|
|
2874
|
-
let resp = qn.webhooks.get_enabled_count().await?;
|
|
2875
|
-
```
|
|
2876
|
-
|
|
2877
|
-
```python
|
|
2878
|
-
# Python
|
|
2879
|
-
resp = await qn.webhooks.get_enabled_count()
|
|
2880
|
-
```
|
|
2881
|
-
|
|
2882
|
-
```typescript
|
|
2883
|
-
// Node.js
|
|
2884
|
-
const resp = await qn.webhooks.getEnabledCount();
|
|
2885
|
-
```
|
|
2886
|
-
|
|
2887
|
-
```ruby
|
|
2888
|
-
# Ruby
|
|
2889
|
-
resp = JSON.parse(qn.webhooks.get_enabled_count)
|
|
2890
|
-
```
|
|
2891
|
-
|
|
2892
|
-
---
|
|
2893
|
-
|
|
2894
|
-
### KV Store Client
|
|
2895
|
-
|
|
2896
|
-
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/`.
|
|
2897
|
-
|
|
2898
|
-
#### Sets
|
|
2899
|
-
|
|
2900
|
-
##### `create_set` / `createSet`
|
|
2901
|
-
|
|
2902
|
-
Stores a single string value under a key.
|
|
2903
|
-
|
|
2904
|
-
**Parameters**: `key` (string, required), `value` (string, required).
|
|
2905
|
-
|
|
2906
|
-
**Returns**: nothing.
|
|
2907
|
-
|
|
2908
|
-
```rust
|
|
2909
|
-
// Rust
|
|
2910
|
-
qn.kvstore.create_set(&CreateSetParams {
|
|
2911
|
-
key: "my-key".to_string(),
|
|
2912
|
-
value: "hello".to_string(),
|
|
2913
|
-
}).await?;
|
|
2914
|
-
```
|
|
2915
|
-
|
|
2916
|
-
```python
|
|
2917
|
-
# Python
|
|
2918
|
-
await qn.kvstore.create_set(key="my-key", value="hello")
|
|
2919
|
-
```
|
|
2920
|
-
|
|
2921
|
-
```typescript
|
|
2922
|
-
// Node.js
|
|
2923
|
-
await qn.kvstore.createSet({ key: "my-key", value: "hello" });
|
|
2924
|
-
```
|
|
2925
|
-
|
|
2926
|
-
```ruby
|
|
2927
|
-
# Ruby
|
|
2928
|
-
qn.kvstore.create_set(key: "my-key", value: "hello")
|
|
2929
|
-
```
|
|
2930
|
-
|
|
2931
|
-
##### `get_sets` / `getSets`
|
|
2932
|
-
|
|
2933
|
-
Paginated page of key/value entries.
|
|
2934
|
-
|
|
2935
|
-
**Parameters** (all optional): `limit` (i64), `cursor` (string).
|
|
2936
|
-
|
|
2937
|
-
**Returns**: `GetSetsResponse` — `{ data: KvSetEntry[], cursor: string }`.
|
|
2938
|
-
|
|
2939
|
-
```rust
|
|
2940
|
-
// Rust
|
|
2941
|
-
let resp = qn.kvstore.get_sets(&Default::default()).await?;
|
|
2942
|
-
```
|
|
2943
|
-
|
|
2944
|
-
```python
|
|
2945
|
-
# Python
|
|
2946
|
-
resp = await qn.kvstore.get_sets()
|
|
2947
|
-
```
|
|
2948
|
-
|
|
2949
|
-
```typescript
|
|
2950
|
-
// Node.js
|
|
2951
|
-
const resp = await qn.kvstore.getSets();
|
|
2952
|
-
```
|
|
2953
|
-
|
|
2954
|
-
```ruby
|
|
2955
|
-
# Ruby
|
|
2956
|
-
resp = JSON.parse(qn.kvstore.get_sets({}))
|
|
2957
|
-
```
|
|
2958
|
-
|
|
2959
|
-
##### `get_set` / `getSet`
|
|
2960
|
-
|
|
2961
|
-
Returns the value stored under a key.
|
|
2962
|
-
|
|
2963
|
-
**Parameters**: `key` (string, required).
|
|
2964
|
-
|
|
2965
|
-
**Returns**: `GetSetResponse` with `value`.
|
|
2966
|
-
|
|
2967
|
-
```rust
|
|
2968
|
-
// Rust
|
|
2969
|
-
let resp = qn.kvstore.get_set("my-key").await?;
|
|
2970
|
-
```
|
|
2971
|
-
|
|
2972
|
-
```python
|
|
2973
|
-
# Python
|
|
2974
|
-
resp = await qn.kvstore.get_set("my-key")
|
|
2975
|
-
```
|
|
2976
|
-
|
|
2977
|
-
```typescript
|
|
2978
|
-
// Node.js
|
|
2979
|
-
const resp = await qn.kvstore.getSet("my-key");
|
|
2980
|
-
```
|
|
2981
|
-
|
|
2982
|
-
```ruby
|
|
2983
|
-
# Ruby
|
|
2984
|
-
resp = JSON.parse(qn.kvstore.get_set(key: "my-key"))
|
|
2985
|
-
```
|
|
2986
|
-
|
|
2987
|
-
##### `bulk_sets` / `bulkSets`
|
|
2988
|
-
|
|
2989
|
-
Adds and/or deletes multiple sets in a single request.
|
|
2990
|
-
|
|
2991
|
-
**Parameters** (at least one required): `add_sets` (map<string,string>, optional), `delete_sets` (string[], optional).
|
|
2992
|
-
|
|
2993
|
-
**Returns**: nothing.
|
|
2994
|
-
|
|
2995
|
-
```rust
|
|
2996
|
-
// Rust
|
|
2997
|
-
use std::collections::HashMap;
|
|
2998
|
-
|
|
2999
|
-
let mut add_sets = HashMap::new();
|
|
3000
|
-
add_sets.insert("k1".to_string(), "v1".to_string());
|
|
3001
|
-
qn.kvstore.bulk_sets(&BulkSetsParams {
|
|
3002
|
-
add_sets: Some(add_sets),
|
|
3003
|
-
delete_sets: Some(vec!["old-key".to_string()]),
|
|
3004
|
-
}).await?;
|
|
3005
|
-
```
|
|
3006
|
-
|
|
3007
|
-
```python
|
|
3008
|
-
# Python
|
|
3009
|
-
await qn.kvstore.bulk_sets(
|
|
3010
|
-
add_sets={"k1": "v1"},
|
|
3011
|
-
delete_sets=["old-key"],
|
|
3012
|
-
)
|
|
3013
|
-
```
|
|
3014
|
-
|
|
3015
|
-
```typescript
|
|
3016
|
-
// Node.js
|
|
3017
|
-
await qn.kvstore.bulkSets({
|
|
3018
|
-
addSets: { k1: "v1" },
|
|
3019
|
-
deleteSets: ["old-key"],
|
|
3020
|
-
});
|
|
3021
|
-
```
|
|
3022
|
-
|
|
3023
|
-
```ruby
|
|
3024
|
-
# Ruby
|
|
3025
|
-
qn.kvstore.bulk_sets(add_sets: { "k1" => "v1" }, delete_sets: ["old-key"])
|
|
3026
|
-
```
|
|
3027
|
-
|
|
3028
|
-
##### `delete_set` / `deleteSet`
|
|
3029
|
-
|
|
3030
|
-
Deletes a single set.
|
|
3031
|
-
|
|
3032
|
-
**Parameters**: `key` (string, required).
|
|
3033
|
-
|
|
3034
|
-
**Returns**: nothing.
|
|
3035
|
-
|
|
3036
|
-
```rust
|
|
3037
|
-
// Rust
|
|
3038
|
-
qn.kvstore.delete_set("my-key").await?;
|
|
3039
|
-
```
|
|
3040
|
-
|
|
3041
|
-
```python
|
|
3042
|
-
# Python
|
|
3043
|
-
await qn.kvstore.delete_set("my-key")
|
|
3044
|
-
```
|
|
3045
|
-
|
|
3046
|
-
```typescript
|
|
3047
|
-
// Node.js
|
|
3048
|
-
await qn.kvstore.deleteSet("my-key");
|
|
3049
|
-
```
|
|
3050
|
-
|
|
3051
|
-
```ruby
|
|
3052
|
-
# Ruby
|
|
3053
|
-
qn.kvstore.delete_set(key: "my-key")
|
|
3054
|
-
```
|
|
3055
|
-
|
|
3056
|
-
#### Lists
|
|
3057
|
-
|
|
3058
|
-
##### `create_list` / `createList`
|
|
3059
|
-
|
|
3060
|
-
Creates a list under a key, seeded with the initial items.
|
|
3061
|
-
|
|
3062
|
-
**Parameters**: `key` (string, required), `items` (string[], required).
|
|
3063
|
-
|
|
3064
|
-
**Returns**: nothing.
|
|
3065
|
-
|
|
3066
|
-
```rust
|
|
3067
|
-
// Rust
|
|
3068
|
-
qn.kvstore.create_list(&CreateListParams {
|
|
3069
|
-
key: "my-list".to_string(),
|
|
3070
|
-
items: vec!["0xabc".to_string(), "0xdef".to_string()],
|
|
3071
|
-
}).await?;
|
|
3072
|
-
```
|
|
3073
|
-
|
|
3074
|
-
```python
|
|
3075
|
-
# Python
|
|
3076
|
-
await qn.kvstore.create_list(key="my-list", items=["0xabc", "0xdef"])
|
|
3077
|
-
```
|
|
3078
|
-
|
|
3079
|
-
```typescript
|
|
3080
|
-
// Node.js
|
|
3081
|
-
await qn.kvstore.createList({ key: "my-list", items: ["0xabc", "0xdef"] });
|
|
3082
|
-
```
|
|
3083
|
-
|
|
3084
|
-
```ruby
|
|
3085
|
-
# Ruby
|
|
3086
|
-
qn.kvstore.create_list(key: "my-list", items: ["0xabc", "0xdef"])
|
|
3087
|
-
```
|
|
3088
|
-
|
|
3089
|
-
##### `get_lists` / `getLists`
|
|
3090
|
-
|
|
3091
|
-
Paginated page of list keys.
|
|
3092
|
-
|
|
3093
|
-
**Parameters** (all optional): `limit` (i64), `cursor` (string).
|
|
3094
|
-
|
|
3095
|
-
**Returns**: `GetListsResponse` — `{ data: { keys: string[] }, cursor: string }`.
|
|
3096
|
-
|
|
3097
|
-
```rust
|
|
3098
|
-
// Rust
|
|
3099
|
-
let resp = qn.kvstore.get_lists(&Default::default()).await?;
|
|
3100
|
-
```
|
|
3101
|
-
|
|
3102
|
-
```python
|
|
3103
|
-
# Python
|
|
3104
|
-
resp = await qn.kvstore.get_lists()
|
|
3105
|
-
```
|
|
3106
|
-
|
|
3107
|
-
```typescript
|
|
3108
|
-
// Node.js
|
|
3109
|
-
const resp = await qn.kvstore.getLists();
|
|
3110
|
-
```
|
|
3111
|
-
|
|
3112
|
-
```ruby
|
|
3113
|
-
# Ruby
|
|
3114
|
-
resp = JSON.parse(qn.kvstore.get_lists({}))
|
|
3115
|
-
```
|
|
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)
|
|
3116
32
|
|
|
3117
|
-
|
|
33
|
+
This file covers project structure, install index, and how to develop and release the SDK.
|
|
3118
34
|
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
**Parameters**: `key` (string, required); optional `limit` (i64), `cursor` (string).
|
|
3122
|
-
|
|
3123
|
-
**Returns**: `GetListResponse` — `{ data: { items: string[] }, cursor: string }`.
|
|
3124
|
-
|
|
3125
|
-
```rust
|
|
3126
|
-
// Rust
|
|
3127
|
-
let resp = qn.kvstore.get_list("my-list", &Default::default()).await?;
|
|
3128
|
-
```
|
|
3129
|
-
|
|
3130
|
-
```python
|
|
3131
|
-
# Python
|
|
3132
|
-
resp = await qn.kvstore.get_list("my-list")
|
|
3133
|
-
```
|
|
3134
|
-
|
|
3135
|
-
```typescript
|
|
3136
|
-
// Node.js
|
|
3137
|
-
const resp = await qn.kvstore.getList("my-list");
|
|
3138
|
-
```
|
|
3139
|
-
|
|
3140
|
-
```ruby
|
|
3141
|
-
# Ruby
|
|
3142
|
-
resp = JSON.parse(qn.kvstore.get_list(key: "my-list"))
|
|
3143
|
-
```
|
|
3144
|
-
|
|
3145
|
-
##### `update_list` / `updateList`
|
|
3146
|
-
|
|
3147
|
-
Adds and/or removes items in a single operation.
|
|
3148
|
-
|
|
3149
|
-
**Parameters**: `key` (string, required); optional: `add_items` (string[]), `remove_items` (string[]).
|
|
3150
|
-
|
|
3151
|
-
**Returns**: nothing.
|
|
3152
|
-
|
|
3153
|
-
```rust
|
|
3154
|
-
// Rust
|
|
3155
|
-
qn.kvstore.update_list(
|
|
3156
|
-
"my-list",
|
|
3157
|
-
&UpdateListParams {
|
|
3158
|
-
add_items: Some(vec!["0x456".to_string()]),
|
|
3159
|
-
remove_items: Some(vec!["0xabc".to_string()]),
|
|
3160
|
-
},
|
|
3161
|
-
).await?;
|
|
3162
|
-
```
|
|
3163
|
-
|
|
3164
|
-
```python
|
|
3165
|
-
# Python
|
|
3166
|
-
await qn.kvstore.update_list(
|
|
3167
|
-
"my-list",
|
|
3168
|
-
add_items=["0x456"],
|
|
3169
|
-
remove_items=["0xabc"],
|
|
3170
|
-
)
|
|
3171
|
-
```
|
|
3172
|
-
|
|
3173
|
-
```typescript
|
|
3174
|
-
// Node.js
|
|
3175
|
-
await qn.kvstore.updateList("my-list", {
|
|
3176
|
-
addItems: ["0x456"],
|
|
3177
|
-
removeItems: ["0xabc"],
|
|
3178
|
-
});
|
|
3179
|
-
```
|
|
3180
|
-
|
|
3181
|
-
```ruby
|
|
3182
|
-
# Ruby
|
|
3183
|
-
qn.kvstore.update_list(key: "my-list", add_items: ["0x456"], remove_items: ["0xabc"])
|
|
3184
|
-
```
|
|
3185
|
-
|
|
3186
|
-
##### `add_list_item` / `addListItem`
|
|
3187
|
-
|
|
3188
|
-
Appends a single item to a list.
|
|
3189
|
-
|
|
3190
|
-
**Parameters**: `key` (string, required), `item` (string, required).
|
|
3191
|
-
|
|
3192
|
-
**Returns**: nothing.
|
|
3193
|
-
|
|
3194
|
-
```rust
|
|
3195
|
-
// Rust
|
|
3196
|
-
qn.kvstore.add_list_item(
|
|
3197
|
-
"my-list",
|
|
3198
|
-
&AddListItemParams { item: "0x123".to_string() },
|
|
3199
|
-
).await?;
|
|
3200
|
-
```
|
|
3201
|
-
|
|
3202
|
-
```python
|
|
3203
|
-
# Python
|
|
3204
|
-
await qn.kvstore.add_list_item("my-list", "0x123")
|
|
3205
|
-
```
|
|
3206
|
-
|
|
3207
|
-
```typescript
|
|
3208
|
-
// Node.js
|
|
3209
|
-
await qn.kvstore.addListItem("my-list", { item: "0x123" });
|
|
3210
|
-
```
|
|
3211
|
-
|
|
3212
|
-
```ruby
|
|
3213
|
-
# Ruby
|
|
3214
|
-
qn.kvstore.add_list_item(key: "my-list", item: "0x123")
|
|
3215
|
-
```
|
|
3216
|
-
|
|
3217
|
-
##### `list_contains_item` / `listContainsItem`
|
|
3218
|
-
|
|
3219
|
-
Checks whether a list contains a specific item.
|
|
3220
|
-
|
|
3221
|
-
**Parameters**: `key` (string, required), `item` (string, required).
|
|
3222
|
-
|
|
3223
|
-
**Returns**: `ListContainsItemResponse` with `exists: bool`.
|
|
3224
|
-
|
|
3225
|
-
```rust
|
|
3226
|
-
// Rust
|
|
3227
|
-
let resp = qn.kvstore.list_contains_item("my-list", "0x123").await?;
|
|
3228
|
-
```
|
|
3229
|
-
|
|
3230
|
-
```python
|
|
3231
|
-
# Python
|
|
3232
|
-
resp = await qn.kvstore.list_contains_item("my-list", "0x123")
|
|
3233
|
-
```
|
|
3234
|
-
|
|
3235
|
-
```typescript
|
|
3236
|
-
// Node.js
|
|
3237
|
-
const resp = await qn.kvstore.listContainsItem("my-list", "0x123");
|
|
3238
|
-
```
|
|
3239
|
-
|
|
3240
|
-
```ruby
|
|
3241
|
-
# Ruby
|
|
3242
|
-
resp = JSON.parse(qn.kvstore.list_contains_item(key: "my-list", item: "0x123"))
|
|
3243
|
-
```
|
|
3244
|
-
|
|
3245
|
-
##### `delete_list_item` / `deleteListItem`
|
|
3246
|
-
|
|
3247
|
-
Removes a single item from a list.
|
|
3248
|
-
|
|
3249
|
-
**Parameters**: `key` (string, required), `item` (string, required).
|
|
3250
|
-
|
|
3251
|
-
**Returns**: nothing.
|
|
3252
|
-
|
|
3253
|
-
```rust
|
|
3254
|
-
// Rust
|
|
3255
|
-
qn.kvstore.delete_list_item("my-list", "0x123").await?;
|
|
3256
|
-
```
|
|
3257
|
-
|
|
3258
|
-
```python
|
|
3259
|
-
# Python
|
|
3260
|
-
await qn.kvstore.delete_list_item("my-list", "0x123")
|
|
3261
|
-
```
|
|
3262
|
-
|
|
3263
|
-
```typescript
|
|
3264
|
-
// Node.js
|
|
3265
|
-
await qn.kvstore.deleteListItem("my-list", "0x123");
|
|
3266
|
-
```
|
|
3267
|
-
|
|
3268
|
-
```ruby
|
|
3269
|
-
# Ruby
|
|
3270
|
-
qn.kvstore.delete_list_item(key: "my-list", item: "0x123")
|
|
3271
|
-
```
|
|
3272
|
-
|
|
3273
|
-
##### `delete_list` / `deleteList`
|
|
3274
|
-
|
|
3275
|
-
Deletes a list and all of its items.
|
|
3276
|
-
|
|
3277
|
-
**Parameters**: `key` (string, required).
|
|
3278
|
-
|
|
3279
|
-
**Returns**: nothing.
|
|
3280
|
-
|
|
3281
|
-
```rust
|
|
3282
|
-
// Rust
|
|
3283
|
-
qn.kvstore.delete_list("my-list").await?;
|
|
3284
|
-
```
|
|
3285
|
-
|
|
3286
|
-
```python
|
|
3287
|
-
# Python
|
|
3288
|
-
await qn.kvstore.delete_list("my-list")
|
|
3289
|
-
```
|
|
3290
|
-
|
|
3291
|
-
```typescript
|
|
3292
|
-
// Node.js
|
|
3293
|
-
await qn.kvstore.deleteList("my-list");
|
|
3294
|
-
```
|
|
3295
|
-
|
|
3296
|
-
```ruby
|
|
3297
|
-
# Ruby
|
|
3298
|
-
qn.kvstore.delete_list(key: "my-list")
|
|
3299
|
-
```
|
|
3300
|
-
|
|
3301
|
-
## Error Handling
|
|
3302
|
-
|
|
3303
|
-
Every binding exposes a typed exception hierarchy derived from the core `SdkError`
|
|
3304
|
-
enum (`crates/core/src/errors.rs`). Catch the base class (`QuickNodeError` /
|
|
3305
|
-
`QuickNodeSdk::Error` / `SdkError`) for any SDK-originated failure, or a specific
|
|
3306
|
-
subclass to branch on transport vs. API semantics.
|
|
3307
|
-
|
|
3308
|
-
| Logical class | When it fires | Extra fields |
|
|
3309
|
-
|----------------------|-------------------------------------------------------------|----------------------|
|
|
3310
|
-
| `QuickNodeError` | base class; catches everything below | — |
|
|
3311
|
-
| `ConfigError` | invalid config or URL surfaced at construction time | — |
|
|
3312
|
-
| `HttpError` | transport failure that isn't a timeout/connect | — |
|
|
3313
|
-
| `TimeoutError` | request timed out (subclass of `HttpError`) | — |
|
|
3314
|
-
| `ConnectionError` | connection refused / DNS / TLS (subclass of `HttpError`) | — |
|
|
3315
|
-
| `ApiError` | non-2xx HTTP response | `status`, `body` |
|
|
3316
|
-
| `DecodeError` | 2xx response but JSON parse failed | `body` |
|
|
3317
|
-
|
|
3318
|
-
Per-language names:
|
|
3319
|
-
|
|
3320
|
-
- **Rust** — pattern-match on `SdkError { Http, Api, Decode, UrlParse, Config }`; use `err.http_kind()` to classify `Http` into `Timeout`, `Connect`, or `Other`.
|
|
3321
|
-
- **Python** — `QuickNodeError`, `ConfigError`, `HttpError`, `TimeoutError`, `ConnectionError`, `ApiError`, `DecodeError` (importable from `sdk`).
|
|
3322
|
-
- **Node.js** — same class names, importable from `@quicknode/sdk`, all extend `Error`.
|
|
3323
|
-
- **Ruby** — `QuickNodeSdk::Error`, `QuickNodeSdk::ConfigError`, `QuickNodeSdk::HttpError`, `QuickNodeSdk::TimeoutError`, `QuickNodeSdk::ConnectionError`, `QuickNodeSdk::ApiError`, `QuickNodeSdk::DecodeError`; all extend `StandardError`. Hash-key validation still raises `ArgumentError`.
|
|
35
|
+
## Project Structure
|
|
3324
36
|
|
|
3325
|
-
```rust
|
|
3326
|
-
// Rust
|
|
3327
|
-
match qn.admin.show_endpoint("missing").await {
|
|
3328
|
-
Ok(resp) => println!("{:?}", resp.data),
|
|
3329
|
-
Err(SdkError::Api { status, body }) if status.as_u16() == 404 => {
|
|
3330
|
-
eprintln!("not found: {body}")
|
|
3331
|
-
}
|
|
3332
|
-
Err(e) if matches!(e.http_kind(), Some(HttpKind::Timeout)) => eprintln!("timed out"),
|
|
3333
|
-
Err(e) => eprintln!("other: {e}"),
|
|
3334
|
-
}
|
|
3335
37
|
```
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
#
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
raise
|
|
3347
|
-
except TimeoutError:
|
|
3348
|
-
print("timed out")
|
|
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
|
|
3349
48
|
```
|
|
3350
49
|
|
|
3351
|
-
|
|
3352
|
-
// Node.js
|
|
3353
|
-
import { ApiError, TimeoutError } from "@quicknode/sdk";
|
|
3354
|
-
try {
|
|
3355
|
-
await qn.admin.showEndpoint("missing");
|
|
3356
|
-
} catch (e) {
|
|
3357
|
-
if (e instanceof ApiError && e.status === 404) console.error("not found:", e.body);
|
|
3358
|
-
else if (e instanceof TimeoutError) console.error("timed out");
|
|
3359
|
-
else throw e;
|
|
3360
|
-
}
|
|
3361
|
-
```
|
|
50
|
+
## Installation
|
|
3362
51
|
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
rescue QuickNodeSdk::TimeoutError
|
|
3370
|
-
warn "timed out"
|
|
3371
|
-
end
|
|
3372
|
-
```
|
|
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) |
|
|
3373
58
|
|
|
3374
59
|
## Development
|
|
3375
60
|
|
|
@@ -3391,7 +76,7 @@ cargo check
|
|
|
3391
76
|
cargo test -p quicknode-sdk
|
|
3392
77
|
|
|
3393
78
|
# Python (from project root)
|
|
3394
|
-
just python-setup
|
|
79
|
+
just python-setup
|
|
3395
80
|
just python-build
|
|
3396
81
|
|
|
3397
82
|
# Node.js (from npm/)
|
|
@@ -3435,99 +120,76 @@ QN_SDK__API_KEY=replaceme ruby ruby/examples/streams.rb
|
|
|
3435
120
|
|
|
3436
121
|
### Releasing
|
|
3437
122
|
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
#### Rust crate only (crates.io)
|
|
3441
|
-
|
|
3442
|
-
```bash
|
|
3443
|
-
# 1. Bump the version in crates/core/Cargo.toml (e.g. 0.1.0 → 0.1.0-alpha.5)
|
|
3444
|
-
# Pre-release identifiers use SemVer 2.0 syntax: MAJOR.MINOR.PATCH-<id>.<N>
|
|
3445
|
-
# Examples: 0.1.0-alpha.4, 0.2.0-beta.1, 0.2.0-rc.1
|
|
3446
|
-
|
|
3447
|
-
# 2. Commit and push
|
|
3448
|
-
git commit -am "chore: release quicknode-sdk 0.1.0-alpha.5"
|
|
3449
|
-
git push
|
|
3450
|
-
|
|
3451
|
-
# 3. Validate the tarball (no upload)
|
|
3452
|
-
cargo publish -p quicknode-sdk --dry-run
|
|
3453
|
-
|
|
3454
|
-
# 4. Publish (requires `cargo login` with a crates.io token)
|
|
3455
|
-
cargo publish -p quicknode-sdk
|
|
3456
|
-
```
|
|
3457
|
-
|
|
3458
|
-
The first publish claims the `quicknode-sdk` name permanently. Published versions are immutable — you cannot overwrite or delete them (only `cargo yank`, which hides but doesn't remove).
|
|
3459
|
-
|
|
3460
|
-
#### All bindings together (Python / Node / Ruby)
|
|
3461
|
-
|
|
3462
|
-
macOS (Apple Silicon) artifacts are built locally rather than on GitHub Actions to avoid the ~10× runner cost. Linux artifacts are built by CI when a GitHub release is published.
|
|
3463
|
-
|
|
3464
|
-
1. **Bump versions and commit:**
|
|
3465
|
-
```bash
|
|
3466
|
-
just release 0.2.0
|
|
3467
|
-
git push
|
|
3468
|
-
```
|
|
3469
|
-
|
|
3470
|
-
2. **Create the GitHub release** via the GitHub UI:
|
|
3471
|
-
- **Releases → Draft a new release**.
|
|
3472
|
-
- **Choose a tag** → type `v0.2.0` → **Create new tag on publish**.
|
|
3473
|
-
- Target branch: `main`.
|
|
3474
|
-
- Fill in title and notes (or click **Generate release notes**).
|
|
3475
|
-
- Click **Publish release**.
|
|
3476
|
-
|
|
3477
|
-
This creates + pushes the tag and triggers `.github/workflows/release.yml`, which builds Linux artifacts and attaches them to the release.
|
|
3478
|
-
|
|
3479
|
-
3. **Build macOS arm64 artifacts locally and append them to the release:**
|
|
3480
|
-
```bash
|
|
3481
|
-
just macos-build-and-publish 0.2.0
|
|
3482
|
-
```
|
|
3483
|
-
|
|
3484
|
-
Step 3 requires the [`gh` CLI](https://cli.github.com/) authenticated to the repo. Intel macOS (`x86_64-apple-darwin`) is not shipped — users on Intel Macs install from source.
|
|
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:
|
|
3485
124
|
|
|
3486
|
-
|
|
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.
|
|
3487
127
|
|
|
3488
|
-
|
|
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.
|
|
3489
129
|
|
|
3490
|
-
|
|
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.
|
|
3491
131
|
|
|
3492
|
-
|
|
132
|
+
#### Two-phase flow
|
|
3493
133
|
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
**Per-release flow:**
|
|
3499
|
-
|
|
3500
|
-
1. **Bump the npm version** in `npm/package.json` (e.g. `3.0.0-alpha.4` → `3.0.0-alpha.5`), commit, and push to `main`. (Bump the overall project version in `just release <version>` as part of the normal release flow above — this sets the git tag.)
|
|
3501
|
-
|
|
3502
|
-
2. **Create the GitHub release** via the GitHub UI:
|
|
3503
|
-
- Go to **Releases → Draft a new release**.
|
|
3504
|
-
- Click **Choose a tag**, type the new tag (e.g. `v0.1.0-alpha.5`), and select **Create new tag on publish**.
|
|
3505
|
-
- Target branch: `main`.
|
|
3506
|
-
- Fill in the title and release notes (or click **Generate release notes**).
|
|
3507
|
-
- Click **Publish release**.
|
|
134
|
+
```bash
|
|
135
|
+
# Phase 1: build a fully-staged GitHub release
|
|
136
|
+
just release-prepare 0.2.0
|
|
3508
137
|
|
|
3509
|
-
|
|
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.
|
|
3510
141
|
|
|
3511
|
-
|
|
142
|
+
# Phase 2: publish to crates.io + trigger registry publish workflows
|
|
143
|
+
just release-publish 0.2.0
|
|
144
|
+
```
|
|
3512
145
|
|
|
3513
|
-
|
|
3514
|
-
```bash
|
|
3515
|
-
just node-build
|
|
3516
|
-
gh release upload v0.1.0-alpha.5 npm/index.darwin-arm64.node
|
|
3517
|
-
```
|
|
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`.
|
|
3518
147
|
|
|
3519
|
-
|
|
3520
|
-
```bash
|
|
3521
|
-
gh workflow run publish-npm.yml -f tag=v0.1.0-alpha.5 -f npm_tag=next
|
|
3522
|
-
```
|
|
148
|
+
#### Building blocks
|
|
3523
149
|
|
|
3524
|
-
|
|
3525
|
-
```bash
|
|
3526
|
-
npm view @quicknode/sdk dist-tags
|
|
3527
|
-
# Expected: next: 3.0.0-alpha.5, latest: 2.6.0 (unchanged)
|
|
3528
|
-
```
|
|
150
|
+
If a phase fails partway, resume with the individual recipes — they are also useful for reruns:
|
|
3529
151
|
|
|
3530
|
-
|
|
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` |
|
|
171
|
+
|---|---|
|
|
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
|
+
```
|
|
3531
193
|
|
|
3532
194
|
## License
|
|
3533
195
|
|