From 5ff1477a499a9f3fa7e6e519e452ed10db767cea Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Tue, 21 Apr 2026 15:00:13 -0400 Subject: [PATCH 1/2] Naming update --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 4 ++-- CLAUDE.md | 6 +++--- Justfile | 2 +- LICENSE | 2 +- README.md | 10 +++++----- crates/core/Cargo.toml | 3 ++- crates/core/LICENSE | 21 +++++++++++++++++++++ crates/core/examples/admin.rs | 2 +- crates/core/examples/admin_e2e.rs | 9 +++++++-- crates/core/examples/kvstore_e2e.rs | 2 +- crates/core/examples/streams.rs | 2 +- crates/core/examples/streams_e2e.rs | 2 +- crates/core/examples/webhooks_e2e.rs | 2 +- crates/node/Cargo.toml | 3 ++- crates/node/src/errors.rs | 2 +- crates/node/src/lib.rs | 2 +- crates/node/src/streams_destination.rs | 2 +- crates/python-stubs/Cargo.toml | 1 + crates/python/Cargo.toml | 5 +++-- crates/python/src/errors.rs | 2 +- crates/python/src/lib.rs | 2 +- crates/python/src/streams_destination.rs | 2 +- crates/ruby/Cargo.toml | 3 ++- crates/ruby/src/errors.rs | 2 +- crates/ruby/src/lib.rs | 2 +- 26 files changed, 64 insertions(+), 33 deletions(-) create mode 100644 crates/core/LICENSE diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e282992..4430f58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: run: cargo clippy --workspace --lib --tests -- -D warnings - name: cargo test - run: cargo test -p sdk-core --lib + run: cargo test -p quicknode-sdk --lib python: runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1fc6137..420d651 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,12 +14,12 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Package crate - run: cargo package -p sdk-core --allow-dirty + run: cargo package -p quicknode-sdk --allow-dirty - uses: actions/upload-artifact@v4 with: name: rust-crate - path: target/package/sdk-core-*.crate + path: target/package/quicknode-sdk-*.crate build-python: strategy: diff --git a/CLAUDE.md b/CLAUDE.md index 7fc106d..5f2ad54 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,9 +7,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ### Rust ```bash cargo check # Type check all crates -cargo build -p sdk-core # Build core crate -cargo test -p sdk-core --lib # Run tests (excludes examples) -cargo run --example admin -p sdk-core # Run example (requires QN_API_KEY env var) +cargo build -p quicknode-sdk # Build core crate +cargo test -p quicknode-sdk --lib # Run tests (excludes examples) +cargo run --example admin -p quicknode-sdk # Run example (requires QN_API_KEY env var) ``` ### Python diff --git a/Justfile b/Justfile index 185b701..6c68642 100644 --- a/Justfile +++ b/Justfile @@ -70,7 +70,7 @@ macos-build-and-publish version: echo "Uploaded macOS arm64 artifacts to v{{version}}" test: - cargo test -p sdk-core --lib + cargo test -p quicknode-sdk --lib lint: cargo clippy --workspace --lib --tests -- -D warnings diff --git a/LICENSE b/LICENSE index 35f04da..b4f5848 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 QuickNode, Inc. +Copyright (c) 2026 Quicknode, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8c6c003..9916f85 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Construct the SDK once, then reach into the four sub-clients (`admin`, `streams` ```rust // Rust -use sdk_core::{QuickNodeSdk, SdkFullConfig}; +use quicknode_sdk::{QuickNodeSdk, SdkFullConfig}; #[tokio::main] async fn main() -> Result<(), Box> { @@ -3388,7 +3388,7 @@ Use the commands in the `Justfile` for the setup and build commands. ```bash # Core library cargo check -cargo test -p sdk-core +cargo test -p quicknode-sdk # Python (from project root) just python-setup-env @@ -3401,7 +3401,7 @@ just node-build just ruby-build # Rust -cargo build -p sdk-core +cargo build -p quicknode-sdk ``` ### Testing @@ -3410,13 +3410,13 @@ cargo build -p sdk-core just test ``` -Runs the Rust unit tests for `sdk-core` using [wiremock](https://github.com/LukeMathWalker/wiremock-rs) to mock HTTP responses — no API key required. +Runs the Rust unit tests for `quicknode-sdk` using [wiremock](https://github.com/LukeMathWalker/wiremock-rs) to mock HTTP responses — no API key required. ### Examples ```bash # Rust -QN_SDK__API_KEY=replaceme cargo run --example admin -p sdk-core --features rust +QN_SDK__API_KEY=replaceme cargo run --example admin -p quicknode-sdk --features rust # Python QN_SDK__API_KEY=replaceme uv run python/examples/admin.py diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index a16ed81..5cc8280 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,10 +1,11 @@ [package] -name = "sdk-core" +name = "quicknode-sdk" version.workspace = true edition.workspace = true license.workspace = true description = "Core library for quicknode sdk" repository = "https://github.com/quiknode-labs/sdk" +readme = "../../README.md" keywords = ["quicknode", "blockchain", "web3", "sdk"] categories = ["api-bindings", "web-programming"] diff --git a/crates/core/LICENSE b/crates/core/LICENSE new file mode 100644 index 0000000..b4f5848 --- /dev/null +++ b/crates/core/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Quicknode, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/core/examples/admin.rs b/crates/core/examples/admin.rs index a630769..7e7079d 100644 --- a/crates/core/examples/admin.rs +++ b/crates/core/examples/admin.rs @@ -1,4 +1,4 @@ -use sdk_core::{admin::GetEndpointsRequest, QuickNodeSdk, SdkFullConfig}; +use quicknode_sdk::{admin::GetEndpointsRequest, QuickNodeSdk, SdkFullConfig}; #[tokio::main] #[allow(clippy::unwrap_used, clippy::expect_used)] diff --git a/crates/core/examples/admin_e2e.rs b/crates/core/examples/admin_e2e.rs index f6c1d3e..a2cae71 100644 --- a/crates/core/examples/admin_e2e.rs +++ b/crates/core/examples/admin_e2e.rs @@ -1,4 +1,4 @@ -use sdk_core::{ +use quicknode_sdk::{ admin::{ BulkAddTagRequest, BulkRemoveTagRequest, BulkUpdateEndpointStatusRequest, CreateDomainMaskRequest, CreateEndpointRequest, CreateIpRequest, CreateJwtRequest, @@ -827,7 +827,12 @@ async fn main() { .get_endpoints(&GetEndpointsRequest::default()) .await { - Err(e) if matches!(e.http_kind(), Some(sdk_core::errors::HttpKind::Timeout)) => { + Err(e) + if matches!( + e.http_kind(), + Some(quicknode_sdk::errors::HttpKind::Timeout) + ) => + { println!("timed out as expected"); } other => eprintln!("expected timeout, got {other:?}"), diff --git a/crates/core/examples/kvstore_e2e.rs b/crates/core/examples/kvstore_e2e.rs index 63487db..1ac76e7 100644 --- a/crates/core/examples/kvstore_e2e.rs +++ b/crates/core/examples/kvstore_e2e.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use sdk_core::{ +use quicknode_sdk::{ kvstore::{ AddListItemParams, BulkSetsParams, CreateListParams, CreateSetParams, UpdateListParams, }, diff --git a/crates/core/examples/streams.rs b/crates/core/examples/streams.rs index 1a3c752..c84d621 100644 --- a/crates/core/examples/streams.rs +++ b/crates/core/examples/streams.rs @@ -1,4 +1,4 @@ -use sdk_core::{ +use quicknode_sdk::{ streams::{ CreateStreamParams, DestinationAttributes, StreamDataset, StreamMetadataLocation, StreamRegion, StreamStatus, WebhookAttributes, diff --git a/crates/core/examples/streams_e2e.rs b/crates/core/examples/streams_e2e.rs index 8e882bb..25792e8 100644 --- a/crates/core/examples/streams_e2e.rs +++ b/crates/core/examples/streams_e2e.rs @@ -1,6 +1,6 @@ use std::{thread, time::Duration}; -use sdk_core::{ +use quicknode_sdk::{ streams::{ CreateStreamParams, DestinationAttributes, ListStreamsParams, StreamDataset, StreamMetadataLocation, StreamRegion, StreamStatus, TestFilterParams, UpdateStreamParams, diff --git a/crates/core/examples/webhooks_e2e.rs b/crates/core/examples/webhooks_e2e.rs index acacaed..2405b36 100644 --- a/crates/core/examples/webhooks_e2e.rs +++ b/crates/core/examples/webhooks_e2e.rs @@ -1,6 +1,6 @@ use std::{thread, time::Duration}; -use sdk_core::{ +use quicknode_sdk::{ webhooks::{ ActivateWebhookParams, CreateWebhookFromTemplateParams, EvmWalletFilterTemplate, GetWebhooksParams, TemplateArgs, UpdateWebhookParams, WebhookDestinationAttributes, diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 2561f47..478bb08 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true description = "Node.js bindings for quicknode sdk" +publish = false [lints] workspace = true @@ -12,7 +13,7 @@ workspace = true crate-type = ["cdylib"] [dependencies] -sdk-core = { path = "../core", features = ["node"] } +quicknode-sdk = { path = "../core", features = ["node"] } tokio = { version = "1", features = ["rt-multi-thread"] } napi = { version = "2", features = ["async", "tokio_rt", "serde-json"] } napi-derive = "2" diff --git a/crates/node/src/errors.rs b/crates/node/src/errors.rs index 65db478..80605f8 100644 --- a/crates/node/src/errors.rs +++ b/crates/node/src/errors.rs @@ -1,5 +1,5 @@ use napi::{bindgen_prelude::Error, Status}; -use sdk_core::errors::{HttpKind, SdkError}; +use quicknode_sdk::errors::{HttpKind, SdkError}; // napi-rs can only throw plain napi::Error with a status + message. To give // callers a typed class hierarchy in JS, we encode the variant as a structured diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs index 467b83d..f2df34c 100644 --- a/crates/node/src/lib.rs +++ b/crates/node/src/lib.rs @@ -1,6 +1,6 @@ use napi::bindgen_prelude::*; use napi_derive::napi; -use sdk_core as core; +use quicknode_sdk as core; mod errors; mod streams_destination; diff --git a/crates/node/src/streams_destination.rs b/crates/node/src/streams_destination.rs index 5898911..c0f523a 100644 --- a/crates/node/src/streams_destination.rs +++ b/crates/node/src/streams_destination.rs @@ -1,6 +1,6 @@ use napi::bindgen_prelude::*; use napi_derive::napi; -use sdk_core as core; +use quicknode_sdk as core; // napi(object) cannot represent the flattened DestinationAttributes enum on // core's stream types, so these wrappers carry it as serde_json::Value. diff --git a/crates/python-stubs/Cargo.toml b/crates/python-stubs/Cargo.toml index 2b3125e..53e6067 100644 --- a/crates/python-stubs/Cargo.toml +++ b/crates/python-stubs/Cargo.toml @@ -3,6 +3,7 @@ name = "sdk-python-stubs" version.workspace = true edition.workspace = true license.workspace = true +publish = false [lints] workspace = true diff --git a/crates/python/Cargo.toml b/crates/python/Cargo.toml index c0d9339..d656c91 100644 --- a/crates/python/Cargo.toml +++ b/crates/python/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true description = "Python bindings for Quicknode SDK" +publish = false [lints] workspace = true @@ -13,10 +14,10 @@ name = "_core" crate-type = ["cdylib", "rlib"] [features] -extension-module = ["pyo3/extension-module", "sdk-core/extension-module"] +extension-module = ["pyo3/extension-module", "quicknode-sdk/extension-module"] [dependencies] -sdk-core = { path = "../core", features = ["python"] } +quicknode-sdk = { path = "../core", features = ["python"] } pyo3 = { workspace = true } pyo3-async-runtimes = { workspace = true, features = ["tokio-runtime"] } pyo3-stub-gen = { workspace = true } diff --git a/crates/python/src/errors.rs b/crates/python/src/errors.rs index 2c65d2d..2532c74 100644 --- a/crates/python/src/errors.rs +++ b/crates/python/src/errors.rs @@ -3,7 +3,7 @@ use pyo3::{ exceptions::{PyException, PyValueError}, prelude::*, }; -use sdk_core::errors::{HttpKind, SdkError}; +use quicknode_sdk::errors::{HttpKind, SdkError}; // Invalid-argument parse errors for user-supplied strings (enum values, etc.) // stay as PyValueError — they're argument errors, not SDK errors. diff --git a/crates/python/src/lib.rs b/crates/python/src/lib.rs index beac9f3..c16bcfc 100644 --- a/crates/python/src/lib.rs +++ b/crates/python/src/lib.rs @@ -3,7 +3,7 @@ use pyo3_stub_gen::{ define_stub_info_gatherer, derive::{gen_stub_pyclass, gen_stub_pymethods}, }; -use sdk_core as core; +use quicknode_sdk as core; mod errors; mod streams_destination; diff --git a/crates/python/src/streams_destination.rs b/crates/python/src/streams_destination.rs index ca428c6..34a14dc 100644 --- a/crates/python/src/streams_destination.rs +++ b/crates/python/src/streams_destination.rs @@ -1,6 +1,6 @@ use pyo3::prelude::*; use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods}; -use sdk_core::streams::{ +use quicknode_sdk::streams::{ AddressBookConfig, AzureAttributes, ClickhouseAttributes, DestinationAttributes, KafkaAttributes, ListStreamsResponse, MongoAttributes, MysqlAttributes, PageInfo, PostgresAttributes, RedisAttributes, S3Attributes, SnowflakeAttributes, Stream, diff --git a/crates/ruby/Cargo.toml b/crates/ruby/Cargo.toml index 177a7ce..1a7eea3 100644 --- a/crates/ruby/Cargo.toml +++ b/crates/ruby/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true description = "Ruby bindings for quicknode sdk" +publish = false [lints] workspace = true @@ -13,7 +14,7 @@ name = "quicknode_sdk" crate-type = ["cdylib"] [dependencies] -sdk-core = { path = "../core", features = ["ruby"] } +quicknode-sdk = { path = "../core", features = ["ruby"] } magnus = { workspace = true } tokio = { version = "1", features = ["rt-multi-thread"] } serde_json = "1.0" diff --git a/crates/ruby/src/errors.rs b/crates/ruby/src/errors.rs index 291436e..ddd59b9 100644 --- a/crates/ruby/src/errors.rs +++ b/crates/ruby/src/errors.rs @@ -1,7 +1,7 @@ use magnus::{ exception::ExceptionClass, prelude::*, value::Opaque, Object, RModule, RObject, Ruby, Value, }; -use sdk_core::errors::{HttpKind, SdkError}; +use quicknode_sdk::errors::{HttpKind, SdkError}; use std::sync::OnceLock; // Class handles are captured at #[magnus::init] time. OnceLock> is diff --git a/crates/ruby/src/lib.rs b/crates/ruby/src/lib.rs index 6a3fd23..73972a7 100644 --- a/crates/ruby/src/lib.rs +++ b/crates/ruby/src/lib.rs @@ -2,7 +2,7 @@ use magnus::{ function, method, prelude::*, r_hash::ForEach, symbol::Symbol, Error, RArray, RHash, Ruby, }; -use sdk_core as core; +use quicknode_sdk as core; mod errors; From 0f8ab969cc4f1e9e302925e260296a7bff166365 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Tue, 21 Apr 2026 15:04:56 -0400 Subject: [PATCH 2/2] Versioning update --- README.md | 26 ++++++++++++++++++++++++++ crates/core/Cargo.toml | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9916f85..c18221d 100644 --- a/README.md +++ b/README.md @@ -3435,6 +3435,30 @@ QN_SDK__API_KEY=replaceme ruby ruby/examples/streams.rb ### Releasing +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`. + +#### Rust crate only (crates.io) + +```bash +# 1. Bump the version in crates/core/Cargo.toml (e.g. 0.1.0 → 0.1.0-alpha.5) +# Pre-release identifiers use SemVer 2.0 syntax: MAJOR.MINOR.PATCH-. +# Examples: 0.1.0-alpha.4, 0.2.0-beta.1, 0.2.0-rc.1 + +# 2. Commit and push +git commit -am "chore: release quicknode-sdk 0.1.0-alpha.5" +git push + +# 3. Validate the tarball (no upload) +cargo publish -p quicknode-sdk --dry-run + +# 4. Publish (requires `cargo login` with a crates.io token) +cargo publish -p quicknode-sdk +``` + +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). + +#### All bindings together (Python / Node / Ruby) + macOS (Apple Silicon) artifacts are built locally rather than on GitHub Actions to avoid the ~10× runner cost. Linux artifacts are still built by CI on tag push. ```bash @@ -3452,6 +3476,8 @@ just macos-build-and-publish 0.2.0 Step 4 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. +`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. + ## License MIT diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 5cc8280..a01239f 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "quicknode-sdk" -version.workspace = true +version = "0.1.0-alpha.4" edition.workspace = true license.workspace = true description = "Core library for quicknode sdk"