@quicknode/sdk 3.0.0-alpha.5 → 3.1.0-alpha.14

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 ADDED
@@ -0,0 +1,246 @@
1
+ # Quicknode SDK
2
+
3
+ A unified SDK for building on Quicknode.
4
+
5
+ Rust SDK with Python, Node.js, and Ruby bindings.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Per-language docs](#per-language-docs)
10
+ - [Project Structure](#project-structure)
11
+ - [Installation](#installation)
12
+ - [Development](#development)
13
+ - [Prerequisites](#prerequisites)
14
+ - [Build Commands](#build-commands)
15
+ - [Testing](#testing)
16
+ - [Examples](#examples)
17
+ - [Releasing](#releasing)
18
+ - [Rust crate only (crates.io)](#rust-crate-only-cratesio)
19
+ - [All bindings together (Python / Node / Ruby)](#all-bindings-together-python--node--ruby)
20
+ - [npm publish (`@quicknode/sdk`)](#npm-publish-quicknodesdk)
21
+ - [PyPI publish (`quicknode-sdk`)](#pypi-publish-quicknode-sdk)
22
+ - [License](#license)
23
+
24
+ ## Per-language docs
25
+
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.
27
+
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)
32
+
33
+ This file covers project structure, install index, and how to develop and release the SDK.
34
+
35
+ ## Project Structure
36
+
37
+ ```
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
48
+ ```
49
+
50
+ ## Installation
51
+
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) |
58
+
59
+ ## Development
60
+
61
+ ### Prerequisites
62
+
63
+ - Rust (stable)
64
+ - Python 3.8+ with [uv](https://docs.astral.sh/uv/)
65
+ - Node.js 18+
66
+ - Ruby 3.0+
67
+ - [just](https://github.com/casey/just)
68
+
69
+ ### Build Commands
70
+
71
+ Use the commands in the `Justfile` for the setup and build commands.
72
+
73
+ ```bash
74
+ # Core library
75
+ cargo check
76
+ cargo test -p quicknode-sdk
77
+
78
+ # Python (from project root)
79
+ just python-setup-env
80
+ just python-build
81
+
82
+ # Node.js (from npm/)
83
+ just node-build
84
+
85
+ # Ruby
86
+ just ruby-build
87
+
88
+ # Rust
89
+ cargo build -p quicknode-sdk
90
+ ```
91
+
92
+ ### Testing
93
+
94
+ ```bash
95
+ just test
96
+ ```
97
+
98
+ Runs the Rust unit tests for `quicknode-sdk` using [wiremock](https://github.com/LukeMathWalker/wiremock-rs) to mock HTTP responses — no API key required.
99
+
100
+ ### Examples
101
+
102
+ ```bash
103
+ # Rust
104
+ QN_SDK__API_KEY=replaceme cargo run --example admin -p quicknode-sdk --features rust
105
+
106
+ # Python
107
+ QN_SDK__API_KEY=replaceme uv run python/examples/admin.py
108
+ QN_SDK__API_KEY=replaceme uv run python/examples/streams.py
109
+
110
+ # Node.js
111
+ cd npm && QN_SDK__API_KEY=replaceme npx tsx examples/admin.ts
112
+ cd npm && QN_SDK__API_KEY=replaceme npx tsx examples/streams.ts
113
+
114
+ # Ruby (build first, then run)
115
+ just ruby-build
116
+ QN_SDK__API_KEY=replaceme ruby ruby/examples/admin.rb
117
+ QN_SDK__API_KEY=replaceme ruby ruby/examples/admin_e2e.rb
118
+ QN_SDK__API_KEY=replaceme ruby ruby/examples/streams.rb
119
+ ```
120
+
121
+ ### Releasing
122
+
123
+ The Rust crate (`quicknode-sdk` on crates.io) versions independently from the Python, Node, and Ruby bindings. Its version lives in `crates/core/Cargo.toml`; the bindings share the workspace version in the root `Cargo.toml`.
124
+
125
+ #### Rust crate only (crates.io)
126
+
127
+ ```bash
128
+ # 1. Bump the version in crates/core/Cargo.toml (e.g. 0.1.0 → 0.1.0-alpha.5)
129
+ # Pre-release identifiers use SemVer 2.0 syntax: MAJOR.MINOR.PATCH-<id>.<N>
130
+ # Examples: 0.1.0-alpha.4, 0.2.0-beta.1, 0.2.0-rc.1
131
+
132
+ # 2. Commit and push
133
+ git commit -am "chore: release quicknode-sdk 0.1.0-alpha.5"
134
+ git push
135
+
136
+ # 3. Validate the tarball (no upload)
137
+ cargo publish -p quicknode-sdk --dry-run
138
+
139
+ # 4. Publish (requires `cargo login` with a crates.io token)
140
+ cargo publish -p quicknode-sdk
141
+ ```
142
+
143
+ 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).
144
+
145
+ #### All bindings together (Python / Node / Ruby)
146
+
147
+ 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.
148
+
149
+ 1. **Bump versions and commit:**
150
+ ```bash
151
+ just release 0.2.0
152
+ git push
153
+ ```
154
+
155
+ 2. **Create the GitHub release** via the GitHub UI:
156
+ - **Releases → Draft a new release**.
157
+ - **Choose a tag** → type `v0.2.0` → **Create new tag on publish**.
158
+ - Target branch: `main`.
159
+ - Fill in title and notes (or click **Generate release notes**).
160
+ - Click **Publish release**.
161
+
162
+ This creates + pushes the tag and triggers `.github/workflows/release.yml`, which builds Linux artifacts and attaches them to the release.
163
+
164
+ 3. **Build macOS arm64 artifacts locally and append them to the release:**
165
+ ```bash
166
+ just macos-build-and-publish 0.2.0
167
+ ```
168
+
169
+ 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.
170
+
171
+ `just release` does **not** bump the Rust crate version (that's managed separately in `crates/core/Cargo.toml`). If you want the Rust crate to move in lockstep with a binding release, bump it manually in the same commit.
172
+
173
+ #### npm publish (`@quicknode/sdk`)
174
+
175
+ The Node package is published to npm as `@quicknode/sdk`. During the 3.x pre-release period, publishes use the `next` dist-tag so `npm install @quicknode/sdk` continues to resolve to the legacy 2.x release while `npm install @quicknode/sdk@next` pulls the rewrite.
176
+
177
+ The npm publish uses [napi-rs's multi-package layout](https://napi.rs/docs/deep-dive/release): one main package plus per-platform sub-packages (`@quicknode/sdk-linux-x64-gnu`, `@quicknode/sdk-darwin-arm64`, etc.) declared as `optionalDependencies`. Publishing is triggered manually via a GitHub Actions workflow so the macOS binary (built locally) can be uploaded to the GitHub release before publish.
178
+
179
+ Anyone with permission to run the `Publish npm` workflow in this repo can cut a release.
180
+
181
+ **Note on versions:** the git tag tracks the overall project version (e.g. `v0.1.0-alpha.5`) and is set in `crates/core/Cargo.toml` / the root `Cargo.toml`. The npm package version is set independently in `npm/package.json` (e.g. `3.0.0-alpha.5`) to stay compatible with the pre-existing `@quicknode/sdk` 2.x series on npm. The two versions do not need to match.
182
+
183
+ **Per-release flow:**
184
+
185
+ 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.)
186
+
187
+ 2. **Create the GitHub release** via the GitHub UI:
188
+ - Go to **Releases → Draft a new release**.
189
+ - Click **Choose a tag**, type the new tag (e.g. `v0.1.0-alpha.5`), and select **Create new tag on publish**.
190
+ - Target branch: `main`.
191
+ - Fill in the title and release notes (or click **Generate release notes**).
192
+ - Click **Publish release**.
193
+
194
+ Publishing the release creates + pushes the tag, which triggers `.github/workflows/release.yml`. CI builds the Linux `.node` artifacts and attaches them to the release you just created.
195
+
196
+ 3. **Wait for `release.yml` to finish.** Confirm the four Linux `index.*.node` artifacts are attached to the release.
197
+
198
+ 4. **Build and upload the macOS arm64 binary** locally (Apple Silicon Mac required):
199
+ ```bash
200
+ just node-build
201
+ gh release upload v0.1.0-alpha.5 npm/index.darwin-arm64.node
202
+ ```
203
+
204
+ 5. **Trigger the publish workflow.** From the GitHub UI: **Actions → Publish npm → Run workflow**, then enter the git tag (`v0.1.0-alpha.5`) and npm dist-tag (`next`). Or via CLI:
205
+ ```bash
206
+ gh workflow run publish-npm.yml -f tag=v0.1.0-alpha.5 -f npm_tag=next
207
+ ```
208
+
209
+ 6. **Verify.**
210
+ ```bash
211
+ npm view @quicknode/sdk dist-tags
212
+ # Expected: next: 3.0.0-alpha.5, latest: 2.6.0 (unchanged)
213
+ ```
214
+
215
+ Users can install the pre-release with `npm install @quicknode/sdk@next`.
216
+
217
+ #### PyPI publish (`quicknode-sdk`)
218
+
219
+ The Python package is published to PyPI as `quicknode-sdk`. Wheels and the sdist are built by `release.yml` on every GitHub release and attached as artifacts; the `Publish PyPI` workflow downloads them from a release tag and uploads to PyPI via `twine`.
220
+
221
+ **Version format:** PyPI uses PEP 440, so pre-releases are written without a hyphen. `0.1.0-alpha.6` → `0.1.0a6` in `pyproject.toml`.
222
+
223
+ **Per-release flow:**
224
+
225
+ 1. **Bump the version** in `pyproject.toml` (e.g. `0.1.0a6` → `0.1.0a7`) and run `uv lock` to refresh `uv.lock`. Commit and push.
226
+
227
+ 2. **Create the GitHub release** as described in the main Releasing section — this triggers `release.yml`, which builds the Linux wheels and sdist and attaches them to the release as `quicknode_sdk-*.whl` and `quicknode_sdk-*.tar.gz`.
228
+
229
+ 3. **Wait for `release.yml` to finish.** Confirm 16 wheels (4 Python versions × 4 Linux targets) and 1 sdist are attached to the release.
230
+
231
+ 4. **Trigger the publish workflow.** From the GitHub UI: **Actions → Publish PyPI → Run workflow**, then enter the git tag. Or via CLI:
232
+ ```bash
233
+ gh workflow run publish-pypi.yml -f tag=v0.1.0-alpha.6
234
+ ```
235
+
236
+ 5. **Verify.**
237
+ ```bash
238
+ pip install quicknode-sdk==0.1.0a6
239
+ python -c "import sdk; print(sdk.QuicknodeSdk)"
240
+ ```
241
+
242
+ **First publish:** the repo secret `PYPI_API_TOKEN` must be set. Project-scoped tokens only work after the project exists on PyPI, so the first upload needs a user-scoped token; rotate to a project-scoped token after.
243
+
244
+ ## License
245
+
246
+ MIT
package/errors.js ADDED
@@ -0,0 +1,121 @@
1
+ // Typed error classes. The Rust binding throws a plain napi Error whose
2
+ // message is tagged "[<kind>|<status>|<body_len>]<msg>\x1f<body>"; parseAndRethrow
3
+ // decodes that and throws an instance of the matching subclass below.
4
+
5
+ class QuicknodeError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = "QuicknodeError";
9
+ }
10
+ }
11
+
12
+ class ConfigError extends QuicknodeError {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = "ConfigError";
16
+ }
17
+ }
18
+
19
+ class HttpError extends QuicknodeError {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = "HttpError";
23
+ }
24
+ }
25
+
26
+ class TimeoutError extends HttpError {
27
+ constructor(message) {
28
+ super(message);
29
+ this.name = "TimeoutError";
30
+ }
31
+ }
32
+
33
+ class ConnectionError extends HttpError {
34
+ constructor(message) {
35
+ super(message);
36
+ this.name = "ConnectionError";
37
+ }
38
+ }
39
+
40
+ class ApiError extends QuicknodeError {
41
+ constructor(message, status, body) {
42
+ super(message);
43
+ this.name = "ApiError";
44
+ this.status = status;
45
+ this.body = body;
46
+ }
47
+ }
48
+
49
+ class DecodeError extends QuicknodeError {
50
+ constructor(message, body) {
51
+ super(message);
52
+ this.name = "DecodeError";
53
+ this.body = body;
54
+ }
55
+ }
56
+
57
+ const TAG_RE = /^\[(Config|Http|Timeout|Connect|Api|Decode)\|([^|]+)\|([^\]]+)\](.*)$/s;
58
+
59
+ function fromNapiError(err) {
60
+ if (!(err instanceof Error)) return err;
61
+ const m = err.message.match(TAG_RE);
62
+ if (!m) return err;
63
+ const [, kind, statusStr, bodyLenStr, rest] = m;
64
+ // rest = "<msg>\x1f<body>". Use body_len (byte length from Rust) to split
65
+ // deterministically — the body may itself contain \x1f, and Api messages
66
+ // embed the body in msg, so scanning for the first separator is unsafe.
67
+ let msg = rest;
68
+ let body = "";
69
+ if (bodyLenStr !== "-") {
70
+ const bodyLen = Number(bodyLenStr);
71
+ const bodyBytes = Buffer.from(rest, "utf8");
72
+ const bodyStart = bodyBytes.length - bodyLen;
73
+ if (bodyStart >= 1 && bodyBytes[bodyStart - 1] === 0x1f) {
74
+ msg = bodyBytes.slice(0, bodyStart - 1).toString("utf8");
75
+ body = bodyBytes.slice(bodyStart).toString("utf8");
76
+ }
77
+ }
78
+ switch (kind) {
79
+ case "Config": return new ConfigError(msg);
80
+ case "Timeout": return new TimeoutError(msg);
81
+ case "Connect": return new ConnectionError(msg);
82
+ case "Http": return new HttpError(msg);
83
+ case "Api": return new ApiError(msg, Number(statusStr), body);
84
+ case "Decode": return new DecodeError(msg, body);
85
+ default: return err;
86
+ }
87
+ }
88
+
89
+ // Wraps an object's methods so thrown napi errors get retagged as typed
90
+ // subclasses. Handles both sync throws and rejected promises.
91
+ function wrapClient(client) {
92
+ return new Proxy(client, {
93
+ get(target, prop) {
94
+ const val = target[prop];
95
+ if (typeof val !== "function") return val;
96
+ return function (...args) {
97
+ try {
98
+ const result = val.apply(target, args);
99
+ if (result && typeof result.then === "function") {
100
+ return result.catch((e) => { throw fromNapiError(e); });
101
+ }
102
+ return result;
103
+ } catch (e) {
104
+ throw fromNapiError(e);
105
+ }
106
+ };
107
+ },
108
+ });
109
+ }
110
+
111
+ module.exports = {
112
+ QuicknodeError,
113
+ ConfigError,
114
+ HttpError,
115
+ TimeoutError,
116
+ ConnectionError,
117
+ ApiError,
118
+ DecodeError,
119
+ fromNapiError,
120
+ wrapClient,
121
+ };
package/index.d.ts CHANGED
@@ -172,7 +172,7 @@ export interface ChainNetwork {
172
172
  /** Numeric chain id, when applicable. */
173
173
  chainId?: number
174
174
  }
175
- /** A blockchain supported by QuickNode along with its networks. */
175
+ /** A blockchain supported by Quicknode along with its networks. */
176
176
  export interface Chain {
177
177
  /** Chain slug (e.g. `ethereum`). */
178
178
  slug: string
@@ -362,7 +362,7 @@ export interface CreateIpRequest {
362
362
  }
363
363
  /** Parameters for `create_domain_mask`. */
364
364
  export interface CreateDomainMaskRequest {
365
- /** Custom domain that will mask the endpoint's QuickNode URL. */
365
+ /** Custom domain that will mask the endpoint's Quicknode URL. */
366
366
  domainMask?: string
367
367
  }
368
368
  /** Parameters for `create_jwt`. */
@@ -469,7 +469,7 @@ export interface Pagination {
469
469
  export interface Endpoint {
470
470
  /** Unique endpoint identifier. */
471
471
  id: string
472
- /** QuickNode-assigned subdomain. */
472
+ /** Quicknode-assigned subdomain. */
473
473
  name: string
474
474
  /** Human-readable label. */
475
475
  label?: string
@@ -1638,18 +1638,6 @@ export interface StellarWalletTransactionsFilterTemplate {
1638
1638
  /** Stellar wallet addresses to match against. */
1639
1639
  wallets: Array<string>
1640
1640
  }
1641
- /**
1642
- * Template identifier paired with its arguments, consumed by
1643
- * `create_webhook_from_template` and `update_webhook_template`. Construct via
1644
- * the typed static factory methods (one per template); do not set fields
1645
- * directly.
1646
- */
1647
- export interface TemplateArgs {
1648
- /** Which filter template these arguments correspond to. */
1649
- templateId: WebhookTemplateId
1650
- /** Template arguments, pre-serialized as a JSON string. */
1651
- value: string
1652
- }
1653
1641
  /** Destination configuration for a webhook. */
1654
1642
  export interface WebhookDestinationAttributes {
1655
1643
  /** Target URL that receives webhook payloads. */
@@ -1683,30 +1671,6 @@ export interface ActivateWebhookParams {
1683
1671
  /** Position to begin (or resume) delivery from. */
1684
1672
  startFrom: WebhookStartFrom
1685
1673
  }
1686
- /** Parameters for `create_webhook_from_template`. */
1687
- export interface CreateWebhookFromTemplateParams {
1688
- /** Human-readable label for the webhook. */
1689
- name: string
1690
- /** Blockchain network to watch (e.g. `ethereum-mainnet`). */
1691
- network: string
1692
- /** Optional email that receives alerts if the webhook terminates. */
1693
- notificationEmail?: string
1694
- /** Destination configuration for delivered payloads. */
1695
- destinationAttributes: WebhookDestinationAttributes
1696
- /** Filter template identifier and its arguments. */
1697
- templateArgs: TemplateArgs
1698
- }
1699
- /** Parameters for `update_webhook_template`. */
1700
- export interface UpdateWebhookTemplateParams {
1701
- /** New human-readable name. */
1702
- name?: string
1703
- /** New notification email. */
1704
- notificationEmail?: string
1705
- /** New destination configuration. */
1706
- destinationAttributes?: WebhookDestinationAttributes
1707
- /** New template identifier and arguments. */
1708
- templateArgs: TemplateArgs
1709
- }
1710
1674
  /** A webhook's full configuration and current state. */
1711
1675
  export interface Webhook {
1712
1676
  /** Unique webhook identifier. */
@@ -1728,10 +1692,21 @@ export interface Webhook {
1728
1692
  /** Destination-specific configuration as a JSON string. */
1729
1693
  destinationAttributes?: string
1730
1694
  }
1695
+ /** Pagination metadata returned alongside a paginated webhooks list. */
1696
+ export interface WebhookPageInfo {
1697
+ /** Page size used for this response. */
1698
+ limit: number
1699
+ /** Starting index of this page within the full result set. */
1700
+ offset: number
1701
+ /** Total number of webhooks matching the query across all pages. */
1702
+ total: number
1703
+ }
1731
1704
  /** Response from `list_webhooks`. */
1732
1705
  export interface ListWebhooksResponse {
1733
1706
  /** Webhooks on the current page. */
1734
1707
  data: Array<Webhook>
1708
+ /** Pagination metadata for the response. */
1709
+ pageInfo: WebhookPageInfo
1735
1710
  }
1736
1711
  /** Response from `get_enabled_count` for webhooks. */
1737
1712
  export interface WebhookEnabledCountResponse {
@@ -1830,7 +1805,20 @@ export interface ListStreamsResponseNode {
1830
1805
  data: Array<StreamNode>
1831
1806
  pageInfo: PageInfo
1832
1807
  }
1833
- export declare class QuickNodeSdk {
1808
+ export interface CreateWebhookFromTemplateParamsNode {
1809
+ name: string
1810
+ network: string
1811
+ notificationEmail?: string
1812
+ destinationAttributes: WebhookDestinationAttributes
1813
+ templateArgs: any
1814
+ }
1815
+ export interface UpdateWebhookTemplateParamsNode {
1816
+ name?: string
1817
+ notificationEmail?: string
1818
+ destinationAttributes?: WebhookDestinationAttributes
1819
+ templateArgs: any
1820
+ }
1821
+ export declare class QuicknodeSdk {
1834
1822
  /** Creates a new SDK instance from an explicit configuration. */
1835
1823
  constructor(config: SdkFullConfig)
1836
1824
  /** Returns the admin sub-client. */
@@ -1842,7 +1830,7 @@ export declare class QuickNodeSdk {
1842
1830
  /** Returns the kvstore sub-client. */
1843
1831
  get kvstore(): KvStoreApiClient
1844
1832
  /** Creates a new SDK instance using configuration from environment variables. */
1845
- static fromEnv(): QuickNodeSdk
1833
+ static fromEnv(): QuicknodeSdk
1846
1834
  }
1847
1835
  export declare class AdminApiClient {
1848
1836
  /**
@@ -1949,7 +1937,7 @@ export declare class AdminApiClient {
1949
1937
  deleteIp(id: string, ipId: string): Promise<DeleteBoolResponse>
1950
1938
  /**
1951
1939
  * Adds a domain mask to an endpoint — a custom domain used to hide the
1952
- * endpoint's QuickNode URL so requests can be routed through your own
1940
+ * endpoint's Quicknode URL so requests can be routed through your own
1953
1941
  * domain.
1954
1942
  */
1955
1943
  createDomainMask(id: string, params?: CreateDomainMaskRequest | undefined | null): Promise<void>
@@ -2034,7 +2022,7 @@ export declare class AdminApiClient {
2034
2022
  */
2035
2023
  getAccountMetrics(params: GetAccountMetricsRequest): Promise<GetAccountMetricsResponse>
2036
2024
  /**
2037
- * Returns all chains supported by QuickNode along with their networks.
2025
+ * Returns all chains supported by Quicknode along with their networks.
2038
2026
  * Each entry includes the chain slug and its network slugs and names.
2039
2027
  */
2040
2028
  listChains(): Promise<ListChainsResponse>
@@ -2250,7 +2238,7 @@ export declare class WebhooksApiClient {
2250
2238
  * filters. An optional `notification_email` receives alerts if the
2251
2239
  * webhook terminates.
2252
2240
  */
2253
- createWebhookFromTemplate(params: CreateWebhookFromTemplateParams): Promise<Webhook>
2241
+ createWebhookFromTemplate(params: CreateWebhookFromTemplateParamsNode): Promise<Webhook>
2254
2242
  /**
2255
2243
  * Updates an existing template-backed webhook, modifying its template
2256
2244
  * arguments and optionally its name, notification email, and destination
@@ -2259,7 +2247,7 @@ export declare class WebhooksApiClient {
2259
2247
  * generated automatically if not provided. Templates cover EVM chains,
2260
2248
  * Solana, Bitcoin, XRPL, Hyperliquid, and Stellar.
2261
2249
  */
2262
- updateWebhookTemplate(webhookId: string, params: UpdateWebhookTemplateParams): Promise<Webhook>
2250
+ updateWebhookTemplate(webhookId: string, params: UpdateWebhookTemplateParamsNode): Promise<Webhook>
2263
2251
  }
2264
2252
  export declare class KvStoreApiClient {
2265
2253
  /** Creates a new set, storing a single string value under the given key. */
Binary file
package/index.js ADDED
@@ -0,0 +1,328 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'index.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./index.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('@quicknode/sdk-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'index.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./index.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('@quicknode/sdk-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'index.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./index.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('@quicknode/sdk-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'index.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./index.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('@quicknode/sdk-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'index.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./index.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('@quicknode/sdk-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'index.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./index.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('@quicknode/sdk-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'index.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./index.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('@quicknode/sdk-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'index.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./index.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('@quicknode/sdk-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'index.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./index.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('@quicknode/sdk-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'index.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./index.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('@quicknode/sdk-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'index.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./index.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('@quicknode/sdk-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'index.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./index.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('@quicknode/sdk-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'index.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./index.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('@quicknode/sdk-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'index.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./index.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@quicknode/sdk-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'index.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./index.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@quicknode/sdk-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'index.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./index.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@quicknode/sdk-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'index.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./index.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@quicknode/sdk-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'index.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./index.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('@quicknode/sdk-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { StreamRegion, StreamDataset, StreamDestination, FilterLanguage, StreamMetadataLocation, ProductType, StreamStatus, WebhookTemplateId, WebhookStartFrom, QuicknodeSdk, AdminApiClient, StreamsApiClient, WebhooksApiClient, KvStoreApiClient } = nativeBinding
314
+
315
+ module.exports.StreamRegion = StreamRegion
316
+ module.exports.StreamDataset = StreamDataset
317
+ module.exports.StreamDestination = StreamDestination
318
+ module.exports.FilterLanguage = FilterLanguage
319
+ module.exports.StreamMetadataLocation = StreamMetadataLocation
320
+ module.exports.ProductType = ProductType
321
+ module.exports.StreamStatus = StreamStatus
322
+ module.exports.WebhookTemplateId = WebhookTemplateId
323
+ module.exports.WebhookStartFrom = WebhookStartFrom
324
+ module.exports.QuicknodeSdk = QuicknodeSdk
325
+ module.exports.AdminApiClient = AdminApiClient
326
+ module.exports.StreamsApiClient = StreamsApiClient
327
+ module.exports.WebhooksApiClient = WebhooksApiClient
328
+ module.exports.KvStoreApiClient = KvStoreApiClient
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quicknode/sdk",
3
- "version": "3.0.0-alpha.5",
3
+ "version": "3.1.0-alpha.14",
4
4
  "description": "Quicknode SDK",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
@@ -18,7 +18,9 @@
18
18
  "sdk.js",
19
19
  "sdk.d.ts",
20
20
  "sdk.mjs",
21
+ "errors.js",
21
22
  "browser.js",
23
+ "README.md",
22
24
  "*.node"
23
25
  ],
24
26
  "napi": {
@@ -44,10 +46,10 @@
44
46
  },
45
47
  "license": "MIT",
46
48
  "optionalDependencies": {
47
- "@quicknode/sdk-linux-x64-gnu": "3.0.0-alpha.5",
48
- "@quicknode/sdk-linux-arm64-gnu": "3.0.0-alpha.5",
49
- "@quicknode/sdk-linux-x64-musl": "3.0.0-alpha.5",
50
- "@quicknode/sdk-linux-arm64-musl": "3.0.0-alpha.5",
51
- "@quicknode/sdk-darwin-arm64": "3.0.0-alpha.5"
49
+ "@quicknode/sdk-linux-x64-gnu": "3.1.0-alpha.14",
50
+ "@quicknode/sdk-linux-arm64-gnu": "3.1.0-alpha.14",
51
+ "@quicknode/sdk-linux-x64-musl": "3.1.0-alpha.14",
52
+ "@quicknode/sdk-linux-arm64-musl": "3.1.0-alpha.14",
53
+ "@quicknode/sdk-darwin-arm64": "3.1.0-alpha.14"
52
54
  }
53
55
  }
package/sdk.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // sdk.d.ts
2
2
  import {
3
- QuickNodeSdk as _QuickNodeSdk,
3
+ QuicknodeSdk as _QuicknodeSdk,
4
4
  SdkFullConfig,
5
5
  WebhookAttributes,
6
6
  S3Attributes,
@@ -72,6 +72,36 @@ export type ListStreamsResponse = Omit<_ListStreamsResponseNode, "data"> & {
72
72
  data: Stream[];
73
73
  };
74
74
 
75
+ // Webhook template args (input). The inner key is `args` rather than the
76
+ // wire's `templateArgs` to avoid `templateArgs.templateArgs.wallets`; the
77
+ // Node binding renames it back before the request.
78
+ export type TemplateArgsInput =
79
+ | { templateId: "evmWalletFilter"; args: EvmWalletFilterTemplate }
80
+ | { templateId: "evmContractEvents"; args: EvmContractEventsTemplate }
81
+ | { templateId: "evmAbiFilter"; args: EvmAbiFilterTemplate }
82
+ | { templateId: "solanaWalletFilter"; args: SolanaWalletFilterTemplate }
83
+ | { templateId: "bitcoinWalletFilter"; args: BitcoinWalletFilterTemplate }
84
+ | { templateId: "xrplWalletFilter"; args: XrplWalletFilterTemplate }
85
+ | { templateId: "hyperliquidWalletEventsFilter"; args: HyperliquidWalletEventsFilterTemplate }
86
+ | {
87
+ templateId: "stellarWalletTransactionsSourceAccountFilter";
88
+ args: StellarWalletTransactionsFilterTemplate;
89
+ };
90
+
91
+ // Replace the napi-generated JSON-blob templateArgs with typed unions.
92
+ type _CreateWebhookFromTemplateParamsNode = import("./index").CreateWebhookFromTemplateParamsNode;
93
+ type _UpdateWebhookTemplateParamsNode = import("./index").UpdateWebhookTemplateParamsNode;
94
+
95
+ export type CreateWebhookFromTemplateParams =
96
+ Omit<_CreateWebhookFromTemplateParamsNode, "templateArgs"> & {
97
+ templateArgs: TemplateArgsInput;
98
+ };
99
+
100
+ export type UpdateWebhookTemplateParams =
101
+ Omit<_UpdateWebhookTemplateParamsNode, "templateArgs"> & {
102
+ templateArgs: TemplateArgsInput;
103
+ };
104
+
75
105
  export type {
76
106
  SdkFullConfig,
77
107
  HttpConfig,
@@ -236,11 +266,10 @@ export type {
236
266
  UpdateWebhookParams,
237
267
  Webhook,
238
268
  ListWebhooksResponse,
269
+ WebhookPageInfo,
239
270
  WebhookEnabledCountResponse,
240
271
  WebhookDestinationAttributes,
241
272
  ActivateWebhookParams,
242
- CreateWebhookFromTemplateParams,
243
- UpdateWebhookTemplateParams,
244
273
  EvmWalletFilterTemplate,
245
274
  EvmContractEventsTemplate,
246
275
  EvmAbiFilterTemplate,
@@ -301,39 +330,60 @@ export interface StreamsApiClientTyped {
301
330
  getEnabledCount(streamType?: string | undefined | null): Promise<import("./index").EnabledCountResponse>;
302
331
  }
303
332
 
304
- export class QuickNodeSdk {
333
+ // Retypes napi's `any` templateArgs to the discriminated union. Keep method
334
+ // signatures in sync with the napi-generated WebhooksApiClient in ./index.d.ts.
335
+ export interface WebhooksApiClientTyped {
336
+ listWebhooks(params?: import("./index").GetWebhooksParams | undefined | null): Promise<import("./index").ListWebhooksResponse>;
337
+ deleteAllWebhooks(): Promise<void>;
338
+ getWebhook(id: string): Promise<import("./index").Webhook>;
339
+ updateWebhook(
340
+ id: string,
341
+ params: import("./index").UpdateWebhookParams
342
+ ): Promise<import("./index").Webhook>;
343
+ deleteWebhook(id: string): Promise<void>;
344
+ pauseWebhook(id: string): Promise<void>;
345
+ activateWebhook(id: string, params: import("./index").ActivateWebhookParams): Promise<void>;
346
+ getEnabledCount(): Promise<import("./index").WebhookEnabledCountResponse>;
347
+ createWebhookFromTemplate(params: CreateWebhookFromTemplateParams): Promise<import("./index").Webhook>;
348
+ updateWebhookTemplate(
349
+ webhookId: string,
350
+ params: UpdateWebhookTemplateParams
351
+ ): Promise<import("./index").Webhook>;
352
+ }
353
+
354
+ export class QuicknodeSdk {
305
355
  constructor(config: SdkFullConfig);
306
- static fromEnv(): QuickNodeSdk;
307
- admin: _QuickNodeSdk["admin"];
356
+ static fromEnv(): QuicknodeSdk;
357
+ admin: _QuicknodeSdk["admin"];
308
358
  streams: StreamsApiClientTyped;
309
- webhooks: _QuickNodeSdk["webhooks"];
310
- kvstore: _QuickNodeSdk["kvstore"];
359
+ webhooks: WebhooksApiClientTyped;
360
+ kvstore: _QuicknodeSdk["kvstore"];
311
361
  }
312
362
 
313
- export class TemplateArgs {
314
- templateId: WebhookTemplateId;
315
- value: string;
316
- static evmWalletFilter(attrs: EvmWalletFilterTemplate): TemplateArgs;
317
- static evmContractEvents(attrs: EvmContractEventsTemplate): TemplateArgs;
318
- static evmAbiFilter(attrs: EvmAbiFilterTemplate): TemplateArgs;
319
- static solanaWalletFilter(attrs: SolanaWalletFilterTemplate): TemplateArgs;
320
- static bitcoinWalletFilter(attrs: BitcoinWalletFilterTemplate): TemplateArgs;
321
- static xrplWalletFilter(attrs: XrplWalletFilterTemplate): TemplateArgs;
322
- static hyperliquidWalletEventsFilter(attrs: HyperliquidWalletEventsFilterTemplate): TemplateArgs;
323
- static stellarWalletTransactionsFilter(attrs: StellarWalletTransactionsFilterTemplate): TemplateArgs;
324
- }
363
+ // Typed static factory methods producing each discriminated variant of
364
+ // TemplateArgsInput. Consumers can also construct the object literal directly.
365
+ export const TemplateArgs: {
366
+ evmWalletFilter(attrs: EvmWalletFilterTemplate): Extract<TemplateArgsInput, { templateId: "evmWalletFilter" }>;
367
+ evmContractEvents(attrs: EvmContractEventsTemplate): Extract<TemplateArgsInput, { templateId: "evmContractEvents" }>;
368
+ evmAbiFilter(attrs: EvmAbiFilterTemplate): Extract<TemplateArgsInput, { templateId: "evmAbiFilter" }>;
369
+ solanaWalletFilter(attrs: SolanaWalletFilterTemplate): Extract<TemplateArgsInput, { templateId: "solanaWalletFilter" }>;
370
+ bitcoinWalletFilter(attrs: BitcoinWalletFilterTemplate): Extract<TemplateArgsInput, { templateId: "bitcoinWalletFilter" }>;
371
+ xrplWalletFilter(attrs: XrplWalletFilterTemplate): Extract<TemplateArgsInput, { templateId: "xrplWalletFilter" }>;
372
+ hyperliquidWalletEventsFilter(attrs: HyperliquidWalletEventsFilterTemplate): Extract<TemplateArgsInput, { templateId: "hyperliquidWalletEventsFilter" }>;
373
+ stellarWalletTransactionsFilter(attrs: StellarWalletTransactionsFilterTemplate): Extract<TemplateArgsInput, { templateId: "stellarWalletTransactionsSourceAccountFilter" }>;
374
+ };
325
375
 
326
376
  // Typed error hierarchy. Any SDK call can throw one of these; catch
327
- // QuickNodeError to handle them all, or a specific subclass for finer control.
328
- export class QuickNodeError extends Error {}
329
- export class ConfigError extends QuickNodeError {}
330
- export class HttpError extends QuickNodeError {}
377
+ // QuicknodeError to handle them all, or a specific subclass for finer control.
378
+ export class QuicknodeError extends Error {}
379
+ export class ConfigError extends QuicknodeError {}
380
+ export class HttpError extends QuicknodeError {}
331
381
  export class TimeoutError extends HttpError {}
332
382
  export class ConnectionError extends HttpError {}
333
- export class ApiError extends QuickNodeError {
383
+ export class ApiError extends QuicknodeError {
334
384
  status: number;
335
385
  body: string;
336
386
  }
337
- export class DecodeError extends QuickNodeError {
387
+ export class DecodeError extends QuicknodeError {
338
388
  body: string;
339
389
  }
package/sdk.js CHANGED
@@ -1,13 +1,13 @@
1
1
  // Exported main sdk file that imports from autogenerated napi-rs file
2
2
  //
3
3
  const _index = require("./index.js");
4
- const { QuickNodeSdk: _QuickNodeSdk } = _index;
4
+ const { QuicknodeSdk: _QuicknodeSdk } = _index;
5
5
  const errors = require("./errors.js");
6
6
 
7
- class QuickNodeSdk {
7
+ class QuicknodeSdk {
8
8
  constructor(config) {
9
9
  try {
10
- this._inner = new _QuickNodeSdk(config);
10
+ this._inner = new _QuicknodeSdk(config);
11
11
  } catch (e) {
12
12
  throw errors.fromNapiError(e);
13
13
  }
@@ -18,9 +18,9 @@ class QuickNodeSdk {
18
18
  }
19
19
 
20
20
  static fromEnv() {
21
- const instance = Object.create(QuickNodeSdk.prototype);
21
+ const instance = Object.create(QuicknodeSdk.prototype);
22
22
  try {
23
- instance._inner = _QuickNodeSdk.fromEnv();
23
+ instance._inner = _QuicknodeSdk.fromEnv();
24
24
  } catch (e) {
25
25
  throw errors.fromNapiError(e);
26
26
  }
@@ -32,67 +32,53 @@ class QuickNodeSdk {
32
32
  }
33
33
  }
34
34
 
35
- // TemplateArgs.value is a pre-serialized JSON string; napi forwards camelCase
36
- // keys from JS but the API expects snake_case, so stringify through these.
37
- function toSnakeCase(str) {
38
- return str.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
39
- }
40
-
41
- function keysToSnakeCase(obj) {
42
- if (obj === null || typeof obj !== "object" || Array.isArray(obj)) return obj;
43
- return Object.fromEntries(
44
- Object.entries(obj).map(([k, v]) => [toSnakeCase(k), keysToSnakeCase(v)])
45
- );
46
- }
47
-
48
- // TemplateArgs wraps the napi-rs generated plain object with typed
49
- // static factory methods. The underlying object has `templateId` (string enum)
50
- // and `value` (JSON string) fields — callers should use the factory methods
51
- // rather than constructing the object directly.
35
+ // TemplateArgs wraps the webhook template input with typed static factory
36
+ // methods. The underlying object is `{ templateId, args }` callers should
37
+ // use the factory methods rather than constructing the object directly.
52
38
  class TemplateArgs {
53
- constructor(templateId, value) {
39
+ constructor(templateId, args) {
54
40
  this.templateId = templateId;
55
- this.value = value;
41
+ this.args = args;
56
42
  }
57
43
 
58
44
  static evmWalletFilter(attrs) {
59
- return new TemplateArgs("EvmWalletFilter", JSON.stringify(keysToSnakeCase(attrs)));
45
+ return new TemplateArgs("evmWalletFilter", attrs);
60
46
  }
61
47
 
62
48
  static evmContractEvents(attrs) {
63
- return new TemplateArgs("EvmContractEvents", JSON.stringify(keysToSnakeCase(attrs)));
49
+ return new TemplateArgs("evmContractEvents", attrs);
64
50
  }
65
51
 
66
52
  static evmAbiFilter(attrs) {
67
- return new TemplateArgs("EvmAbiFilter", JSON.stringify(keysToSnakeCase(attrs)));
53
+ return new TemplateArgs("evmAbiFilter", attrs);
68
54
  }
69
55
 
70
56
  static solanaWalletFilter(attrs) {
71
- return new TemplateArgs("SolanaWalletFilter", JSON.stringify(keysToSnakeCase(attrs)));
57
+ return new TemplateArgs("solanaWalletFilter", attrs);
72
58
  }
73
59
 
74
60
  static bitcoinWalletFilter(attrs) {
75
- return new TemplateArgs("BitcoinWalletFilter", JSON.stringify(keysToSnakeCase(attrs)));
61
+ return new TemplateArgs("bitcoinWalletFilter", attrs);
76
62
  }
77
63
 
78
64
  static xrplWalletFilter(attrs) {
79
- return new TemplateArgs("XrplWalletFilter", JSON.stringify(keysToSnakeCase(attrs)));
65
+ return new TemplateArgs("xrplWalletFilter", attrs);
80
66
  }
81
67
 
82
68
  static hyperliquidWalletEventsFilter(attrs) {
83
- return new TemplateArgs("HyperliquidWalletEventsFilter", JSON.stringify(keysToSnakeCase(attrs)));
69
+ return new TemplateArgs("hyperliquidWalletEventsFilter", attrs);
84
70
  }
85
71
 
86
72
  static stellarWalletTransactionsFilter(attrs) {
87
- return new TemplateArgs("StellarWalletTransactionsSourceAccountFilter", JSON.stringify(keysToSnakeCase(attrs)));
73
+ return new TemplateArgs("stellarWalletTransactionsSourceAccountFilter", attrs);
88
74
  }
89
75
  }
90
76
 
91
77
  module.exports = {
92
78
  ..._index,
93
- QuickNodeSdk,
79
+ QuicknodeSdk,
94
80
  TemplateArgs,
95
- QuickNodeError: errors.QuickNodeError,
81
+ QuicknodeError: errors.QuicknodeError,
96
82
  ConfigError: errors.ConfigError,
97
83
  HttpError: errors.HttpError,
98
84
  TimeoutError: errors.TimeoutError,
package/sdk.mjs CHANGED
@@ -9,7 +9,7 @@ import cjs from './sdk.js';
9
9
 
10
10
  export default cjs;
11
11
  export const {
12
- QuickNodeSdk,
12
+ QuicknodeSdk,
13
13
  TemplateArgs,
14
14
  StreamRegion,
15
15
  StreamDataset,
@@ -24,7 +24,7 @@ export const {
24
24
  StreamsApiClient,
25
25
  WebhooksApiClient,
26
26
  KvStoreApiClient,
27
- QuickNodeError,
27
+ QuicknodeError,
28
28
  ConfigError,
29
29
  HttpError,
30
30
  TimeoutError,