npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@42ch/spoke-connect

v0.11.1

Published

SPOKE connect client library — pure-TS identity derivation, Ed25519 hello signing, and RFC 8785 JCS canonicalization

Readme

@42ch/spoke-connect

SPOKE connect client library (TypeScript) — peer identity derivation, Ed25519 hello signing, RFC 8785 JCS canonicalization, one-JSON-per-message WebSocket framing, and the pure session-core port (sequence, correlation, dispatch gate, nonce store, allowlist).

Published on npm as @42ch/spoke-connect; the version tracks the monorepo lockstep SemVer (asserted by verify:version, bumped by release:bump). The transport is a direct WebSocket ordered reliable stream using plain JSON + WebSocket framing; transport and crypto are dependency-light by design.

What it provides

  • IdentityderivePeerIdFromEd25519Pubkey: protobuf PublicKey → identity multihash 0x00 → base58btc. Ported from tooling/connect-identity-proof/proof.mjs; the normative formula lives in .mstar/specs/spoke-connect.md § Identity binding.
  • Crypto — Ed25519 sign/verify over raw 32-byte keys, WebCrypto primary with an @noble/ed25519 fallback on the same code path; base64url without padding.
  • JCScanonicalHelloBytes(peerId, nonce, host, peerNonce?): RFC 8785 canonicalization of the signed hello object via the pinned canonicalize package — {protocol_version, peer_id, nonce, host} for the initiator hello (4 fields), plus peer_nonce for the responder hello (5 fields, dial binding). Absent optional members are omitted; only present members appear in the canonical object.
  • Session core (src/core/) — behavior port of crates/spoke-connect/src/core/: OutboundSequence / InboundSequence (start 0, exhaustion instead of wrap past 2^53−1), response correlation (session_id / sequence / request_id echo), op dispatch gate (capability ⊆ negotiated, unknown op fails closed), per-sender NonceStore, fail-closed allowlist, thin Session helper, PROTOCOL_VERSION.
  • Node client (src/node/) — connectClient({ url, identity, manifest, remotePubkey, allowlist }): dials a WebSocket, performs the signed hello exchange, validates the session snapshot (peer binding, initial_sequence 0), then routes correlated invokes by request_id with bounded waits. Node-only because it uses ws; the isomorphic src/ modules stay browser-swappable.

Golden-vector parity: tests assert peer_id / JCS bytes / signature byte-identical to the Rust golden vectors. The golden hello vector has a single cross-language source of truth at crates/spoke-connect/tests/fixtures/golden-hello.json; this package loads its registered byte-identical copy (tests/fixtures/golden-hello.json) through the thin test-only loader src/golden.ts (not part of the package exports or npm files).

Install

pnpm add @42ch/spoke-connect

Usage

import { derivePeerIdFromEd25519Pubkey } from "@42ch/spoke-connect";
import { connectClient } from "@42ch/spoke-connect/node";

const seed = new TextEncoder().encode("..."); // 32-byte Ed25519 seed
const remotePubkey = /* the server's 32-byte Ed25519 public key */;

const client = await connectClient({
  url: "ws://127.0.0.1:8080",
  identity: { seed },
  manifest: {
    capabilities: ["spoke-baseline"],
    extensions: {},
    host_id: "host_primary",
    namespaces: ["toy_world"],
    roles: ["data-store"],
    schema_version: 1,
  },
  remotePubkey,
  allowlist: [derivePeerIdFromEd25519Pubkey(remotePubkey)],
});

const response = await client.invoke("check", { /* op payload */ });
client.close();

Core helpers are importable without the client: signHelloEd25519 / verifyHelloEd25519, OutboundSequence, checkResponseCorrelation, dispatchAllowed, NonceStore, isAllowlisted, Session — all from @42ch/spoke-connect.

Test

From the repo root:

pnpm run test:connect-ts

From this directory:

pnpm test
pnpm run typecheck

The two-node interop test (tests/two-node.test.ts) runs an in-process ws server and client over 127.0.0.1:<ephemeral> with bounded waits only. CI runs the suite on Node 20.x — Node ≥ 20.19 takes the WebCrypto Ed25519 path; older patches fall back to @noble/ed25519. The package engine floor is Node ≥ 20.19.0 (@noble/hashes floor, and the first Node line that accepts WebCrypto Ed25519).

Scope

  • Published on npm (@42ch/spoke-connect); ships a built dist/ via tsup (dual CJS/ESM, two isolated entries — browser-safe . and Node ./node).
  • The package consumes the existing connect schemas as-is (@42ch/spoke-schemas runtime dependency; types only from the consumer's perspective); the schema inventory is unchanged.
  • Envelope-level interop over any ordered reliable stream; framing is direct WebSocket per .mstar/specs/spoke-connect.md § Transport framing.
  • The client targets the direct ordered-stream transport.
  • connectClient lives in the Node src/node/ subpath (uses ws); the isomorphic src/ modules are browser-swappable with the native WebSocket.

Publishing

Published via the monorepo release.yml on stable lockstep tags (npm Trusted Publishing OIDC). The build emits dist/ (tsup, dual CJS/ESM); the tarball is packed with pnpm (rewrites workspace:*) and published with the npm CLI.

  • Entry points — two subpaths: . (isomorphic core: identity, crypto, JCS, session core) and ./node (the Node connectClient, which depends on ws). Browser consumers import . only.
  • License — Apache-2.0 via the license field; authoritative text at repository root LICENSE.
  • Versioning — lockstep SemVer with the monorepo (verify:version, release:bump); @42ch/spoke-schemas resolves at the same version from npm.
  • Installationpnpm add @42ch/spoke-connect installs from the npm registry at the lockstep version.