Feat/client pubkey#5
Open
ContextVM-org wants to merge 206 commits into
Open
Conversation
- Replace manual Default impl for EncryptionMode with #[derive(Default)] - Remove unused Instant import from server.rs - Rename is_public_server → is_announced_server to match TS SDK (cd7f411) - Update hardcoded protocol version to 2025-07-02 - Update examples, README, and DESIGN.md accordingly
- Add EPHEMERAL_GIFT_WRAP_KIND (21059) for CEP-19 - Add RELAY_LIST_METADATA_KIND (10002) for CEP-17 - Add tags: RELAY, SUPPORT_ENCRYPTION_EPHEMERAL - Add DEFAULT_BOOTSTRAP_RELAY_URLS matching TS SDK - Add DEFAULT_LRU_SIZE, DEFAULT_TIMEOUT_MS - Add INITIALIZE_METHOD, NOTIFICATIONS_INITIALIZED_METHOD - Add 11 unit tests verifying values against spec and NIP-01 kind ranges
- Update base transport to subscribe to both kind 1059 and 21059 - Handle kind 21059 in both client and server transport event loops - Advertise support_encryption_ephemeral tag in server announcements - Clean up unused imports in base.rs and client.rs tests
- Update gift wrap subscription to use since:now() per CEP-4 - Add rmcp v1.3.0 dependency - Use ProtocolVersion::LATEST in emulated client handshake and tests
- Implement discover_*_typed methods to parse Nostr discovery events into rmcp models - Add NostrMCPProxy::serve_client_handler to support rmcp client handler integration - Add parse_typed_list internal helper for discovery result deserialization
Adds an integration test matrix for RMCP transport, covering local, hybrid, and full relay-based communication scenarios.
…at and file paths
…licate constant - Remove KIND_GIFT_WRAP (duplicate of GIFT_WRAP_KIND); update usage in encryption tests - Remove orphaned doc comment that was attached to the wrong item (DEFAULT_LRU_SIZE) - Promote 6 const-value range assertions from runtime tests to a compile-time const block cargo clippy --all-targets now reports 0 warnings. All 101 tests pass.
…den docs CI / build hygiene - Feature-gate the nak relay e2e suite behind `nak-tests` (Cargo `[[test]]` required-features) so default `cargo test` and CI's `cargo test --all-features` no longer require the external `nak` binary. The tests additionally no-op at runtime when `nak` is absent from PATH (clear stderr note), so `--all-features` stays green without it; with `nak` present they run for real. - Replace the fake `check_relay_ready()` stub (always returned true) with a real TCP connect probe, and surface a `nak`-not-found failure explicitly instead of masking it as a port conflict. - Stop tracking the compiled `c-tests/test_ffi` ELF; the Makefile rebuilds it from `test_ffi.c`, and it is now gitignored. Docs / API surface - headers/contextvm.h: document that `*_ch_recv_timeout(timeout_secs = 0)` is a try-recv (returns immediately), closing the non-blocking-poll gap without new symbols. - lib.rs: mark the test-only re-exports `#[doc(hidden)]` so the published rustdoc surface reflects the real API, not the test plumbing. - Correct misleading module docs in the FFI integration tests: happy_path / mock_relay describe themselves as lifecycle/structure suites (they spin up no relay); only e2e_ffi_nak_relay drives real message flow.
CEP-41 (#97) added contextvm_sdk::Error::OpenStream, which the non-exhaustive match in ErrorCode::from didn't cover — breaking `cargo check --all --all-features` on main after the FFI bindings merge. Map it to ErrorCode::Transport. OpenStreamError is transport-layer sequencing/policy/abort, and its module doc states it mirrors OversizedTransferError, which is mapped the same way (1f9bdb7). The C header exposes no dedicated code.
Add CI workflow for linting, testing, and MSRV checks. Add FFI workflow for cross-platform builds, C tests, and release packaging.
Replace the ContextVM-org/rust-sdk git fork pin with the upstream rmcp 1.8 release, which now ships the transport-worker feature this crate needs. Migrate the 0.x tool_router stored-field pattern to the 1.x macro pattern across tests/examples: #[tool_handler] now generates the dispatch wiring, so the ToolRouter<Self> field (and its initializer and imports) is dead and removed. Verified: fmt, clippy (-D warnings), check/test --all-features (468+ tests, tool routing confirmed functional via test_local_rmcp), no-default-features, and FFI build all green.
UniFFI 0.29.x never published the bindgen CLI to crates.io (the crate is `publish = false` in the Mozilla repo), so `cargo install uniffi-bindgen*` always fails. Install from the git repo instead, pinned to tag v0.29.5 (matches the runtime uniffi = "0.29" metadata format) and targeting the `uniffi-bindgen-cli` workspace member, which produces a binary named `uniffi-bindgen`. Verified end-to-end: the command installs and generates Python/Swift/Kotlin bindings from the built FFI library.
- Bump `nostr-sdk` from 0.43 to 0.44 (no code changes required) - FFI: bump `uniffi` from 0.29 to 0.31, update CI and docs to install `uniffi-bindgen-cli` at tag v0.31.2 and use the renamed binary - Adjust GitHub Actions workflow and AGENTS.md for the new bindgen CLI - Add example Python scripts under `examples/python/` for offline install check, server/tool discovery, and client `tools/list`
rmcp 1.x's #[tool_router] / #[tool_handler] generate the tool-dispatch wiring, so storing a tool_router: ToolRouter<Self> field on the handler struct is dead code and trips the dead_code lint AGENTS.md warns about. The repo's own examples/native_echo_server.rs already omits the field; align the server-transport.md guide with it. Verified the snippet now compiles with zero warnings.
Adds a top-level Makefile to publish contextvm-sdk to crates.io and
validate the release locally. Mirrors .github/workflows/ci.yml's quality
gate (fmt, clippy, check, test all/no-default-features, doc, rmcp local
example), minus the pinned-toolchain MSRV job.
Targets:
- make check full CI quality gate
- make release-dry quality gate + cargo publish --dry-run (--allow-dirty,
so a staged version bump can be validated pre-commit)
- make release quality gate + cargo publish (strict, clean tree only)
Only contextvm-sdk is published; contextvm-ffi ships as prebuilt native
artifacts via ffi.yml, so it is intentionally excluded. Verified
'make release-dry' passes end-to-end on 0.2.0.
- Reduce server-side abort-detection loop from 1000×10 ms (10 s) to 300×5 ms (1.5 s) so genuine abort-delivery bugs fail quickly under the test's result timeout. - Increase client-side result timeout from 5 s to 10 s to absorb CI scheduling jitter on the multi-hop abort+response round trip without masking real regressions.
Add `ClientPubkey` type and inject the caller's Nostr public key (hex) into every inbound request's `extensions` typemap. This allows tool/resource/prompt handlers to identify the caller via `ctx.extensions.get::<ClientPubkey>()`. The feature is always on, unlike the TS adapter's opt-in `_meta` field, and uses rmcp's typed extensions (local-only). The inbound event id remains accessible as `ctx.id`.
Expose the complete verified Nostr event via `InboundEvent` in `extensions` so handlers can access `sig`, `id`, `pubkey`, `tags`, etc. This eliminates the need for handlers to fabricate synthetic events when binding tool calls to the original publishing event (e.g., an MLS key-package coordinator returning the publication event). Also add an `event` field to `IncomingRequest` for the channel seam. FFI types (`FfiIncomingRequest`, the UniFFI `IncomingRequest`) intentionally do not mirror the new field yet because no FFI consumer requires the raw Nostr event, and exposing `nostr_sdk::Event` across the C ABI + UniFFI is non-trivial. Omission is documented in place.
…EP-41) Implement sender-side keepalive for OpenStreamWriter to prevent resource leaks when a client silently disconnects (crash, sleep, network drop) without sending an abort frame. Previously only reader sessions ran keepalive timers, so pure producer streams (e.g. subscription tools) were never probed, leaving writers and downstream producers alive indefinitely. - Add idle_timeout / probe_timeout to OpenStreamWriterOptions to enable keepalive (disabled by default, e.g. for tests). - Arm an idle window when the writer starts streaming; the server keepalive sweep now probes writers via the new `tick` method. - Route inbound pong frames for the stream to the writer to clear probes. - On probe timeout, abort with "Probe timeout", flush a terminal response via the existing on_abort hook, and evict the dead client’s session (mirroring the TS SDK 0.13.8 fix, per CEP-41’s “release local state”). - Reuse the reader idle/probe timeout knobs (one idle/probe pair per stream). - Per CEP-41, only inbound frames reset the idle window; relay writes do not. Closes the silent-disconnect leak and aligns with CEP-41 requirements.
…nit drives The transport's own announcement and initialization drives use the `ANNOUNCEMENT_REQUEST_ID` sentinel as their pubkey. Previously, this sentinel was unconditionally injected into request extensions, handing handlers a bogus caller identity. Now guard the injection so that only real client pubkeys (including those from oversized CEP-22 requests) are exposed via `ClientPubkey`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(server): inject caller's Nostr pubkey into request extensions
Add
ClientPubkeytype and inject the caller's Nostr public key (hex) intoevery inbound request's
extensionstypemap. This allows tool/resource/prompthandlers to identify the caller via
ctx.extensions.get::<ClientPubkey>().The feature is always on, unlike the TS adapter's opt-in
_metafield, anduses rmcp's typed extensions (local-only). The inbound event id remains
accessible as
ctx.id.