Skip to main content

quicknode_sdk/admin/
endpoints.rs

1#[cfg(feature = "rust")]
2use bon::Builder;
3#[cfg(feature = "node")]
4use napi_derive::napi;
5#[cfg(feature = "python")]
6use pyo3::pyclass;
7#[cfg(feature = "python")]
8use pyo3_stub_gen::derive::gen_stub_pyclass;
9use serde::{Deserialize, Serialize};
10
11/// Parameters for `get_endpoints`.
12#[cfg_attr(feature = "python", gen_stub_pyclass)]
13#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
14#[cfg_attr(feature = "node", napi(object))]
15#[cfg_attr(feature = "rust", derive(Builder))]
16#[derive(Debug, Clone, Default, Serialize)]
17pub struct GetEndpointsRequest {
18    /// Maximum number of endpoints returned.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub limit: Option<i32>,
21    /// Starting index into the result set.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub offset: Option<i32>,
24    /// Search by subdomain or label.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub search: Option<String>,
27    /// Field to sort results by.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub sort_by: Option<String>,
30    /// Sort direction (`asc` or `desc`).
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub sort_direction: Option<String>,
33    /// Filter results to endpoints on these networks.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub networks: Option<Vec<String>>,
36    /// Filter results to endpoints in these statuses.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub statuses: Option<Vec<String>>,
39    /// Filter results by label.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub labels: Option<Vec<String>>,
42    /// When true, return only dedicated endpoints.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub dedicated: Option<bool>,
45    /// When true, return only flat-rate endpoints.
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub is_flat_rate: Option<bool>,
48    /// Filter results by associated tag ids.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub tag_ids: Option<Vec<i32>>,
51    /// Filter results by associated tag labels.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub tag_labels: Option<Vec<String>>,
54}
55
56/// Response from `get_endpoints`.
57#[cfg_attr(feature = "python", gen_stub_pyclass)]
58#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
59#[cfg_attr(feature = "node", napi(object))]
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct GetEndpointsResponse {
62    /// Endpoints on the current page.
63    #[serde(default)]
64    pub data: Vec<Endpoint>,
65    /// Pagination metadata for the response.
66    pub pagination: Option<Pagination>,
67    /// Error message when the request did not succeed.
68    pub error: Option<String>,
69}
70
71/// Pagination metadata for admin list responses.
72#[cfg_attr(feature = "python", gen_stub_pyclass)]
73#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
74#[cfg_attr(feature = "node", napi(object))]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct Pagination {
77    /// Total number of items matching the query across all pages.
78    pub total: i64,
79    /// Page size used for this response.
80    pub limit: i32,
81    /// Starting index of this page within the full result set.
82    pub offset: i32,
83}
84
85/// Summary representation of an endpoint in list responses.
86#[cfg_attr(feature = "python", gen_stub_pyclass)]
87#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
88#[cfg_attr(feature = "node", napi(object))]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct Endpoint {
91    /// Unique endpoint identifier.
92    pub id: String,
93    /// Quicknode-assigned subdomain.
94    pub name: String,
95    /// Human-readable label.
96    pub label: Option<String>,
97    /// Current operational status (e.g. `active`, `paused`).
98    pub status: String,
99    /// Blockchain the endpoint serves (e.g. `ethereum`).
100    pub chain: String,
101    /// Specific network within the chain (e.g. `mainnet`).
102    pub network: String,
103    /// Whether the endpoint is dedicated.
104    pub is_dedicated: bool,
105    /// Whether the endpoint is billed at a flat rate.
106    pub is_flat_rate: bool,
107    /// HTTP RPC URL.
108    pub http_url: String,
109    /// WebSocket RPC URL, when available.
110    pub wss_url: Option<String>,
111    /// Tags applied to the endpoint.
112    #[serde(default)]
113    pub tags: Vec<EndpointTag>,
114}
115
116/// Tag reference as returned on an endpoint.
117#[cfg_attr(feature = "python", gen_stub_pyclass)]
118#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
119#[cfg_attr(feature = "node", napi(object))]
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct EndpointTag {
122    /// Tag identifier.
123    pub tag_id: i32,
124    /// Tag label.
125    pub label: String,
126}
127
128/// Parameters for `create_endpoint`.
129#[cfg_attr(feature = "python", gen_stub_pyclass)]
130#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
131#[cfg_attr(feature = "node", napi(object))]
132#[cfg_attr(feature = "rust", derive(Builder))]
133#[derive(Debug, Clone, Default, Serialize)]
134pub struct CreateEndpointRequest {
135    /// Blockchain the endpoint should serve (e.g. `ethereum`).
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub chain: Option<String>,
138    /// Specific network within the chain (e.g. `mainnet`).
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub network: Option<String>,
141}
142
143/// Response from `create_endpoint`.
144#[cfg_attr(feature = "python", gen_stub_pyclass)]
145#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
146#[cfg_attr(feature = "node", napi(object))]
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct CreateEndpointResponse {
149    /// The newly created endpoint.
150    pub data: SingleEndpoint,
151    /// Error message when the request did not succeed.
152    pub error: Option<String>,
153}
154
155/// Full representation of a single endpoint, including its security and rate limits.
156#[cfg_attr(feature = "python", gen_stub_pyclass)]
157#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
158#[cfg_attr(feature = "node", napi(object))]
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct SingleEndpoint {
161    /// Unique endpoint identifier.
162    pub id: String,
163    /// Human-readable label.
164    pub label: Option<String>,
165    /// Current operational status.
166    pub status: Option<String>,
167    /// Blockchain the endpoint serves.
168    pub chain: String,
169    /// Specific network within the chain.
170    pub network: String,
171    /// HTTP RPC URL.
172    pub http_url: String,
173    /// WebSocket RPC URL, when available.
174    pub wss_url: Option<String>,
175    /// Endpoint security configuration.
176    pub security: Option<EndpointSecurity>,
177    /// Endpoint rate limits.
178    pub rate_limits: Option<EndpointRateLimits>,
179    /// Tags applied to the endpoint.
180    #[serde(default)]
181    pub tags: Vec<EndpointTag>,
182}
183
184/// Rate limits applied to an endpoint.
185#[cfg_attr(feature = "python", gen_stub_pyclass)]
186#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
187#[cfg_attr(feature = "node", napi(object))]
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct EndpointRateLimits {
190    /// Whether rate limits are applied per client IP instead of per endpoint.
191    pub rate_limit_by_ip: Option<bool>,
192    /// Account-level rate limit, when applicable.
193    pub account: Option<i32>,
194    /// Requests per second.
195    pub rps: Option<i32>,
196    /// Requests per minute.
197    pub rpm: Option<i32>,
198    /// Requests per day.
199    pub rpd: Option<i32>,
200}
201
202/// Security configuration for an endpoint — the aggregate of tokens, JWTs,
203/// referrers, domain masks, IPs, and request filters plus their enabled
204/// toggles.
205#[cfg_attr(feature = "python", gen_stub_pyclass)]
206#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
207#[cfg_attr(feature = "node", napi(object))]
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct EndpointSecurity {
210    /// Per-feature enabled/disabled toggles.
211    pub options: Option<EndpointSecurityOptions>,
212    /// Authentication tokens configured on the endpoint.
213    pub tokens: Option<Vec<EndpointToken>>,
214    /// JWTs configured on the endpoint.
215    pub jwts: Option<Vec<EndpointJwt>>,
216    /// Allowed referrer URLs/domains.
217    pub referrers: Option<Vec<EndpointReferrer>>,
218    /// Configured domain masks.
219    pub domain_masks: Option<Vec<EndpointDomainMask>>,
220    /// Whitelisted IP addresses.
221    pub ips: Option<Vec<EndpointIp>>,
222    /// Request (method) filters.
223    pub request_filters: Option<Vec<EndpointRequestFilter>>,
224}
225
226/// Boolean toggles controlling which security features are enabled.
227#[cfg_attr(feature = "python", gen_stub_pyclass)]
228#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
229#[cfg_attr(feature = "node", napi(object))]
230#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct EndpointSecurityOptions {
232    /// Whether token authentication is enforced.
233    pub tokens: Option<bool>,
234    /// Whether JWT validation is enforced.
235    pub jwts: Option<bool>,
236    /// Whether domain masking is enabled.
237    #[serde(rename = "domainMasks")]
238    pub domain_masks: Option<bool>,
239    /// Whether IP whitelisting is enforced.
240    pub ips: Option<bool>,
241    /// Whether referrer validation is enforced.
242    pub referrers: Option<bool>,
243    /// Whether request (method) filtering is enforced.
244    #[serde(rename = "requestFilters")]
245    pub request_filters: Option<bool>,
246    /// Custom header used to identify the client IP.
247    #[serde(rename = "ipCustomHeader")]
248    pub ip_custom_header: Option<EndpointIpCustomHeaderOption>,
249}
250
251/// Custom header option value for IP identification.
252#[cfg_attr(feature = "python", gen_stub_pyclass)]
253#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
254#[cfg_attr(feature = "node", napi(object))]
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct EndpointIpCustomHeaderOption {
257    /// Header name (e.g. `X-Forwarded-For`).
258    pub value: Option<String>,
259}
260
261/// Authentication token configured on an endpoint.
262#[cfg_attr(feature = "python", gen_stub_pyclass)]
263#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
264#[cfg_attr(feature = "node", napi(object))]
265#[derive(Clone, Serialize, Deserialize)]
266pub struct EndpointToken {
267    /// Token identifier.
268    pub id: String,
269    /// Token secret.
270    pub token: String,
271}
272
273// Manual Debug redacts `token` so accidental println!/tracing of an
274// EndpointSecurity response does not leak the raw RPC access token.
275impl std::fmt::Debug for EndpointToken {
276    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
277        f.debug_struct("EndpointToken")
278            .field("id", &self.id)
279            .field("token", &"[redacted]")
280            .finish()
281    }
282}
283
284/// JWT configured on an endpoint for signed-request authentication.
285#[cfg_attr(feature = "python", gen_stub_pyclass)]
286#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
287#[cfg_attr(feature = "node", napi(object))]
288#[derive(Clone, Serialize, Deserialize)]
289pub struct EndpointJwt {
290    /// JWT identifier.
291    pub id: String,
292    /// Public key used to verify signed JWTs.
293    pub public_key: String,
294    /// Key identifier (`kid`) embedded in JWT headers.
295    pub kid: String,
296    /// Human-readable name.
297    pub name: String,
298}
299
300// Manual Debug redacts `public_key` — credential material per CLAUDE.md policy.
301impl std::fmt::Debug for EndpointJwt {
302    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
303        f.debug_struct("EndpointJwt")
304            .field("id", &self.id)
305            .field("public_key", &"[redacted]")
306            .field("kid", &self.kid)
307            .field("name", &self.name)
308            .finish()
309    }
310}
311
312/// Allowed referrer entry for request-origin validation.
313#[cfg_attr(feature = "python", gen_stub_pyclass)]
314#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
315#[cfg_attr(feature = "node", napi(object))]
316#[derive(Debug, Clone, Serialize, Deserialize)]
317pub struct EndpointReferrer {
318    /// Referrer entry identifier.
319    pub id: String,
320    /// Allowed referrer URL or domain.
321    pub referrer: Option<String>,
322}
323
324/// Domain mask configured on an endpoint.
325#[cfg_attr(feature = "python", gen_stub_pyclass)]
326#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
327#[cfg_attr(feature = "node", napi(object))]
328#[derive(Debug, Clone, Serialize, Deserialize)]
329pub struct EndpointDomainMask {
330    /// Domain mask identifier.
331    pub id: String,
332    /// Masking domain.
333    pub domain: String,
334}
335
336/// Whitelisted IP address on an endpoint.
337#[cfg_attr(feature = "python", gen_stub_pyclass)]
338#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
339#[cfg_attr(feature = "node", napi(object))]
340#[derive(Debug, Clone, Serialize, Deserialize)]
341pub struct EndpointIp {
342    /// IP entry identifier.
343    pub id: String,
344    /// Whitelisted IP address.
345    pub ip: String,
346}
347
348/// Request (method) filter configured on an endpoint.
349#[cfg_attr(feature = "python", gen_stub_pyclass)]
350#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
351#[cfg_attr(feature = "node", napi(object))]
352#[derive(Debug, Clone, Serialize, Deserialize)]
353pub struct EndpointRequestFilter {
354    /// Filter identifier.
355    pub id: String,
356    /// Whitelisted RPC methods.
357    #[serde(default)]
358    pub method: Vec<String>,
359}
360
361/// Response from `show_endpoint`.
362#[cfg_attr(feature = "python", gen_stub_pyclass)]
363#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
364#[cfg_attr(feature = "node", napi(object))]
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct ShowEndpointResponse {
367    /// The endpoint, when found.
368    pub data: Option<SingleEndpoint>,
369    /// Error message when the request did not succeed.
370    pub error: Option<String>,
371}
372
373/// Parameters for `update_endpoint`.
374#[cfg_attr(feature = "python", gen_stub_pyclass)]
375#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
376#[cfg_attr(feature = "node", napi(object))]
377#[cfg_attr(feature = "rust", derive(Builder))]
378#[derive(Debug, Clone, Default, Serialize)]
379pub struct UpdateEndpointRequest {
380    /// New human-readable label.
381    #[serde(skip_serializing_if = "Option::is_none")]
382    pub label: Option<String>,
383}
384
385/// Parameters for `update_endpoint_status`.
386#[cfg_attr(feature = "python", gen_stub_pyclass)]
387#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
388#[cfg_attr(feature = "node", napi(object))]
389#[cfg_attr(feature = "rust", derive(Builder))]
390#[derive(Debug, Clone, Default, Serialize)]
391pub struct UpdateEndpointStatusRequest {
392    /// New status (`active` or `paused`).
393    pub status: String,
394}
395
396/// Response from `update_endpoint_status`.
397#[cfg_attr(feature = "python", gen_stub_pyclass)]
398#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
399#[cfg_attr(feature = "node", napi(object))]
400#[derive(Debug, Clone, Serialize, Deserialize)]
401pub struct UpdateEndpointStatusResponse {
402    /// Confirmation string returned by the API.
403    pub data: Option<String>,
404    /// Error message when the request did not succeed.
405    pub error: Option<String>,
406}
407
408/// Parameters for `create_tag` (on a specific endpoint).
409#[cfg_attr(feature = "python", gen_stub_pyclass)]
410#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
411#[cfg_attr(feature = "node", napi(object))]
412#[cfg_attr(feature = "rust", derive(Builder))]
413#[derive(Debug, Clone, Default, Serialize)]
414pub struct CreateTagRequest {
415    /// Label for the new tag.
416    #[serde(skip_serializing_if = "Option::is_none")]
417    pub label: Option<String>,
418}
419
420/// Response from `get_endpoint_security`.
421#[cfg_attr(feature = "python", gen_stub_pyclass)]
422#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
423#[cfg_attr(feature = "node", napi(object))]
424#[derive(Debug, Clone, Serialize, Deserialize)]
425pub struct GetEndpointSecurityResponse {
426    /// The endpoint's security configuration.
427    pub data: Option<EndpointSecurity>,
428    /// Error message when the request did not succeed.
429    pub error: Option<String>,
430}