@quicknode/sdk 2.5.2 → 3.0.0-alpha.11
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 +212 -46
- package/browser.js +9 -0
- package/errors.js +121 -0
- package/index.d.ts +2286 -650
- package/index.darwin-arm64.node +0 -0
- package/index.js +328 -0
- 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 +48 -54
- package/sdk.d.ts +389 -0
- package/sdk.js +88 -0
- package/sdk.mjs +34 -0
- package/cjs/index.js +0 -541
- package/cjs/package.json +0 -3
- package/esm/client/client.js +0 -9
- package/esm/client/index.js +0 -2
- package/esm/core/addOns/nftTokenV2/actions.js +0 -107
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTCollectionDetails.js +0 -10
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTs.js +0 -13
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTsByCollection.js +0 -13
- package/esm/core/addOns/nftTokenV2/types/qn_getTokenMetadataByContractAddress.js +0 -10
- package/esm/core/addOns/nftTokenV2/types/qn_getTokenMetadataBySymbol.js +0 -11
- package/esm/core/addOns/nftTokenV2/types/qn_getTransactionsByAddress.js +0 -18
- package/esm/core/addOns/nftTokenV2/types/qn_getTransfersByNFT.js +0 -12
- package/esm/core/addOns/nftTokenV2/types/qn_getWalletTokenBalance.js +0 -12
- package/esm/core/addOns/nftTokenV2/types/qn_getWalletTokenTransactions.js +0 -14
- package/esm/core/addOns/nftTokenV2/types/qn_verifyNFTsOwner.js +0 -11
- package/esm/core/addOns/shared/helpers.js +0 -10
- package/esm/core/chains.js +0 -117
- package/esm/core/core.js +0 -30
- package/esm/core/index.d.ts +0 -558
- package/esm/core/index.js +0 -2
- package/esm/index.js +0 -11
- package/esm/lib/constants.js +0 -4
- package/esm/lib/errors/QNChainNotSupported.js +0 -7
- package/esm/lib/errors/QNInputValidationError.js +0 -10
- package/esm/lib/errors/QNInvalidEnpointUrl.js +0 -7
- package/esm/lib/helpers/getClientHeaders.js +0 -11
- package/esm/lib/helpers/globalFetch.js +0 -13
- package/esm/lib/validation/ValidateInput.js +0 -16
- package/esm/lib/validation/validators.js +0 -15
- package/esm/package.json +0 -4
- package/esm/solana/index.d.ts +0 -76
- package/esm/solana/index.js +0 -2
- package/esm/solana/solana.js +0 -111
package/README.md
CHANGED
|
@@ -1,80 +1,246 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Quicknode SDK
|
|
2
2
|
|
|
3
|
-
A SDK
|
|
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
|
-
[
|
|
10
|
-
[
|
|
11
|
-
[
|
|
12
|
-
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
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)
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
## Per-language docs
|
|
18
25
|
|
|
19
|
-
|
|
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.
|
|
20
27
|
|
|
21
|
-
|
|
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)
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
- `npm install @quicknode/sdk` or `yarn add @quicknode/sdk`
|
|
33
|
+
This file covers project structure, install index, and how to develop and release the SDK.
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
## Project Structure
|
|
27
36
|
|
|
28
|
-
|
|
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
|
|
29
109
|
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
32
113
|
|
|
33
|
-
|
|
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
|
|
34
135
|
|
|
35
|
-
|
|
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
|
|
36
141
|
```
|
|
37
142
|
|
|
38
|
-
|
|
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.)
|
|
39
186
|
|
|
40
|
-
|
|
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**.
|
|
41
193
|
|
|
42
|
-
|
|
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.
|
|
43
195
|
|
|
44
|
-
|
|
196
|
+
3. **Wait for `release.yml` to finish.** Confirm the four Linux `index.*.node` artifacts are attached to the release.
|
|
45
197
|
|
|
46
|
-
|
|
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
|
+
```
|
|
47
203
|
|
|
48
|
-
|
|
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
|
+
```
|
|
49
208
|
|
|
50
|
-
|
|
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
|
+
```
|
|
51
214
|
|
|
52
|
-
|
|
215
|
+
Users can install the pre-release with `npm install @quicknode/sdk@next`.
|
|
53
216
|
|
|
54
|
-
|
|
217
|
+
#### PyPI publish (`quicknode-sdk`)
|
|
55
218
|
|
|
56
|
-
|
|
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`.
|
|
57
220
|
|
|
58
|
-
|
|
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`.
|
|
59
222
|
|
|
60
|
-
|
|
61
|
-
1. cd `packages/apps/examples/sdk-api` from `qn-oss` monorepo root
|
|
62
|
-
1. `cp .env.example .env` and add api key
|
|
63
|
-
1. `nx serve apps-examples-sdk-api`
|
|
64
|
-
1. Then you can send requests to the API, for example: `curl http://localhost:3333/api/nftsByAddress/0xbc08dadccc79c00587d7e6a75bb68ff5fd30f9e0`
|
|
223
|
+
**Per-release flow:**
|
|
65
224
|
|
|
66
|
-
|
|
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.
|
|
67
226
|
|
|
68
|
-
|
|
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`.
|
|
69
228
|
|
|
70
|
-
|
|
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.
|
|
71
230
|
|
|
72
|
-
|
|
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
|
+
```
|
|
73
235
|
|
|
74
|
-
|
|
236
|
+
5. **Verify.**
|
|
237
|
+
```bash
|
|
238
|
+
pip install quicknode-sdk==0.1.0a6
|
|
239
|
+
python -c "import sdk; print(sdk.QuicknodeSdk)"
|
|
240
|
+
```
|
|
75
241
|
|
|
76
|
-
|
|
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.
|
|
77
243
|
|
|
78
|
-
|
|
244
|
+
## License
|
|
79
245
|
|
|
80
|
-
|
|
246
|
+
MIT
|
package/browser.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Native Node.js bindings (.node files compiled from Rust) cannot run in
|
|
2
|
+
// browser environments — they are binary extensions that require the Node.js
|
|
3
|
+
// runtime and OS-level dynamic linking. Bundlers (Webpack, Vite, etc.) that
|
|
4
|
+
// encounter this package in a browser target will load this shim instead,
|
|
5
|
+
// producing a clear error rather than a cryptic binary load failure.
|
|
6
|
+
throw new Error(
|
|
7
|
+
'@quicknode/sdk does not support browser environments. ' +
|
|
8
|
+
'This package requires Node.js.'
|
|
9
|
+
);
|
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
|
+
};
|