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

@byok-sdk/testkit

v0.18.0

Published

BYOK SDK headless device simulator: protocol-level pairing, token renewal, presence, and the built-in negative assertions a host's smoke test would otherwise hand-write

Readme

@byok-sdk/testkit

A headless device simulator for the BYOK device wire (docs/protocol.md §6, §12.3).

If you are integrating the SDK and writing a smoke test, this package is the part of that test you should not be writing yourself: generating an Ed25519 identity, exporting it the way PairRequest.devicePublicKey expects, knowing that a challenge nonce is signed under a domain-separation prefix, knowing what that prefix is, and knowing the exact shapes of pair / challenge / token / presence. All of that is upstream knowledge. Hand-written downstream, it goes quietly green against nothing the moment upstream changes any of it.

Runtime dependencies are @byok-sdk/core and @byok-sdk/protocol, and nothing else — no test framework. The negative assertions are async functions returning structured results, so the same checks run under vitest, under a plain CI script, and inside a Worker. Requires Node ≥ 22.22 (or any runtime exposing WebCrypto Ed25519 on globalThis.crypto.subtle).

Install

npm install --save-dev @byok-sdk/testkit

Usage

import { createDeviceSimulator, runNegativeAssertions, failedAssertions } from '@byok-sdk/testkit';

const simulator = await createDeviceSimulator({
  baseUrl: 'https://cloud.example.com',
  // Optional. Defaults to globalThis.fetch; pass `cloud.fetch` to drive an
  // in-process composition with no socket.
  // fetch: async (input, init) => cloud.fetch(new Request(input, init)),
  host: {
    listPresence: () => cloud.listPresence(tenant),
    revokeDevice: (deviceId) => cloud.revokeDevice(tenant, deviceId),
  },
});

// 1. pair — redeem a one-time pairing code your control plane minted
const session = await simulator.pair(pairingCode, 'ci-device');

// 2. challenge + 3. token — renew without re-pairing
const nonce = await simulator.challenge(session.deviceId);
await simulator.token({
  deviceId: session.deviceId,
  nonce,
  signature: await simulator.identity.signNonce(nonce),
});
// …or `await simulator.renewAccessToken()` for all three in one call.

// 4. presence — published under the device bearer, read back host-side
await simulator.publishPresence('working', 'running the suite', ['salesko.connectors']);
const hints = await simulator.readHostPresence();

// 5. revoke — through your host control plane
await simulator.revoke();

The host adapter

pair, challenge, token, and publishPresence go over HTTP, because those are real mounted routes. Minting a pairing code, reading presence back, and revoking a device are not: the SDK mounts no admin route, and those are in-process calls on ByokCloud / ByokServer. A deployment that exposes them over HTTP chooses the paths and the credential itself, so this package will not guess either — you pass a SimulatorHost with two methods. In-process (above) and HTTP are both a few lines:

const host = {
  async listPresence() {
    const response = await fetch(`${adminUrl}/presence`, { headers: adminAuth });
    return response.json();
  },
  async revokeDevice(deviceId) {
    await fetch(`${adminUrl}/devices/${deviceId}/revoke`, { method: 'POST', headers: adminAuth });
  },
};

Negative assertions

Four checks, each returning { name, ok, expected, actual, response } rather than throwing, so your runner decides what a failure means:

const results = await runNegativeAssertions(simulator, { redeemedPairingCode: pairingCode });
expect(failedAssertions(results)).toEqual([]);

runNegativeAssertions revokes the device as its last step (post-revocation is terminal for that identity), so give it a simulator you are done with.

They can also be called individually — assertUnauthenticatedRejected, assertPairingCodeSingleUse, assertUndomainedSignatureRejected, assertRevokedDeviceChallengeRejected. Each takes an argument that makes it go red, and the repo's pairing-simulator conformance suite exercises exactly that before trusting the green form: an assertion that cannot fail is decoration.

assertUnauthenticatedRejected defaults to PUT /byok/presence — the SDK's own credentialed HTTP surface is device-class. If your deployment publishes admin routes, pass one as the second argument to assert the same property about it.

Replacement condition

This table is the contract with a downstream host: when every row is covered, the hand-written protocol section of your smoke test can be deleted. The left-hand column is the inventory a real integration (salesko, scripts/byok-pairing-smoke.ts, 11 HTTP requests / 15 assertions) was forced to write by hand before this package existed.

| Hand-written detail | Replaced by | Verified by | |---|---|---| | crypto.subtle.generateKey({name:'Ed25519'}) + JWK x export, base64url, 43 chars | createDeviceIdentity(), simulator.identity.publicKeyBase64Url, DEVICE_PUBLIC_KEY_LENGTH | packages/testkit/src/__tests__/identity.test.ts | | byok-nonce-v1\n + nonce domain-separated signing bytes | simulator.identity.signNonce(nonce) — bytes come from @byok-sdk/core's nonceSigningBytes, the single authority; this package defines no domain literal | packages/core/src/__tests__/pairing.test.ts | | pair(pairingCode, deviceName, devicePublicKey) → {deviceId, accessToken} | simulator.pair(pairingCode, deviceName) | conformance pairing simulator › five primitives | | challenge → {nonce} | simulator.challenge(deviceId?) | same | | token(deviceId, nonce, signature) | simulator.token({deviceId, nonce, signature}), or renewAccessToken() | same | | PUT /byok/presence {level, detail, configuredToolsets?} under device bearer | simulator.publishPresence(level, detail?, configuredToolsets?) | same | | Host-side presence read-back | simulator.readHostPresence() via SimulatorHost | same | | Revoke | simulator.revoke() via SimulatorHost | same | | Negative: unauthenticated request → 401 | assertUnauthenticatedRejected | conformance negative assertions hold + can fail | | Negative: pairing code single-use, second redemption → 401 | assertPairingCodeSingleUse | same | | Negative: non-domain-separated signature rejected | assertUndomainedSignatureRejected | same | | Negative: post-revocation challenge → 401 | assertRevokedDeviceChallengeRejected | same |

Not covered, and still yours to write: anything about your own product surface — your admin routes' authorization, your pairing-code issuance UI, and any assertion about what your application does with a paired device.

License

MIT