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

@zkpass/transgate-extension-sdk

v0.1.0

Published

zkPass zkTLS verification SDK for Chrome MV3 extensions. Embed zkPass proof generation directly in your extension's background service worker, with no external extension and no backend required.

Readme

@zkpass/transgate-extension-sdk

zkPass zkTLS verification that runs entirely inside a Chrome MV3 background service worker — no external extension, no backend.

This library is for developers who want to embed zkPass verification directly into their own Chrome MV3 extension. Instead of depending on the external TransGate extension, you bundle proof generation (TLS interception, cryptographic verification, proof assembly) into your own extension and generate zkPass proofs straight from its background service worker. Your extension provides a published schema, AES key material, and triggers the target site's request; the SDK intercepts the matching traffic, builds the zero-knowledge proof, and returns the notary's signature and hashes.

Features

  • Self-contained — no dependency on any external extension or backend.
  • Built for the background SW — targets Chrome MV3 service workers (not web pages).
  • WASM inlined — no separate .wasm asset to host or path-coordinate.
  • Reusable & safe — one reusable instance, automatic WASM cleanup, never hangs (default 2-minute timeout), never throws (result-based errors).
  • Stage-specific error codes — pinpoint exactly where a run failed.

Contents

Installation

npm install @zkpass/transgate-extension-sdk

The package is ESM-only and ships a single bundled entry (dist/index.js) with type declarations (dist/index.d.ts). The WASM is inlined into the bundle — there is no separate asset to host.

Prerequisites

1. Manifest permissions + CSP. The WASM requires wasm-unsafe-eval:

{
  "permissions": ["webRequest", "webNavigation", "tabs", "storage"],
  "host_permissions": ["<all_urls>"],
  "content_security_policy": {
    "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
  }
}

2. Must run in a background service worker. Calling from any other context returns INVALID_CONTEXT (the SDK never throws — it always resolves a result object).

Quick start

import { TransGateExtensionCore } from '@zkpass/transgate-extension-sdk';

const sdk = new TransGateExtensionCore();

const result = await sdk.runZKTLS({
  schemaId,                          // a published zkPass schema id
  appId,                             // a valid zkPass appId (an empty string is rejected by the server)
  aesKeys: { aesKey, aesNonce },     // AES key material you provide (Uint8Array)
  onStatus: (msg) => console.log('[zkTLS]', msg),
  onListening: async () => {
    // The request listener is now registered — make the target site emit the request.
    await chrome.tabs.create({ url: 'https://example.com/path', active: false });
  },
});

if (result.success) {
  const { taskId, validatorAddress, validatorSignature, uHash, publicFields } = result;
  // …forward the proof downstream (e.g. on-chain verification)
} else {
  console.error(result.code, result.error);
}

The instance is reusable — call runZKTLS as many times as you like. WASM is released automatically inside each call; you do not need destroy().

How a verification run works

A single runZKTLS call performs these steps in order and short-circuits on the first failure:

  1. Fetch schemaGET /schema/{schemaId} (→ SCHEMA_FETCH_FAILED)
  2. Verify schema signature (→ SIGNATURE_INVALID)
  3. Allocate a notary nodePOST /sdk/atask (→ NODE_UNREACHABLE)
  4. Intercept the matching request — registers a chrome.webRequest listener and waits for the target site to emit a request matching the schema's API definition (→ INTERCEPT_TIMEOUT)
  5. Generate the proof — 3P-TLS, VOLE, circuit build/evaluation, proof submission (→ SESSION_FAILED / TLS_PROXY_FAILED / PROOF_COMPUTE_FAILED / NODE_VERIFY_FAILED, with PROOF_GENERATION_FAILED as a fallback)

The SDK only observes traffic and builds the proof — it never navigates, logs in, or triggers requests on your behalf. Causing the target request is the caller's responsibility (see below).

Triggering the target request (onListening)

For step 4 to succeed, the target site must emit the matching request after the listener is registered. Use the onListening callback for that exact moment:

await sdk.runZKTLS({
  schemaId, appId, aesKeys,
  onListening: async () => {
    // Open / navigate so the page issues the schema's target API request.
    // Login-gated sites (e.g. social networks) must already be logged in in the same browser profile;
    // the opened tab reuses the browser's cookies.
    await chrome.tabs.create({ url: targetUrl, active: false });
  },
});

onListening fires once, right after the chrome.webRequest listeners are registered. Prefer it over matching the onStatus text (STATUS_MSG.WAITING_MATCH) — onListening is a precise hook and won't break if progress wording changes. If the request is emitted before the listener is registered, it will not be captured and the run ends in INTERCEPT_TIMEOUT.

API reference

The public surface is intentionally small. All exports come from the package root:

import {
  TransGateExtensionCore,
  STATUS_MSG,
  VERSION,
  type RunZKTLSOptions,
  type RunResult,
  type ErrorCode,
  type AesKeyMaterial,
} from '@zkpass/transgate-extension-sdk';

class TransGateExtensionCore

| Member | Signature | Description | |---|---|---| | constructor | new TransGateExtensionCore() | Creates a reusable instance. Holds no cross-call state. | | runZKTLS | (opts: RunZKTLSOptions) => Promise<RunResult> | Runs one full verification. Never throws; all failures are returned as a result. | | destroy | () => Promise<void> | Optional, idempotent manual WASM release. Usually unnecessary — runZKTLS releases WASM internally on every call (success or failure). |

RunZKTLSOptions

| Field | Type | Required | Default | Description | |---|---|---|---|---| | schemaId | string | yes | — | A published zkPass schema id. | | appId | string | yes | — | A valid zkPass appId. An empty string is rejected by the server (HTTP 500). | | aesKeys | { aesKey: Uint8Array; aesNonce: Uint8Array } | yes | — | AES key material injected by the caller. | | httpVersion | string | no | '1.1' | Override the HTTP version. /schema does not always return it, so the caller may set it. | | timeoutMs | number | no | 120000 | Overall timeout. Guarantees the call cannot hang forever. | | onStatus | (msg: string) => void | no | — | Progress callback. msg is one of the STATUS_MSG values. | | onListening | () => void \| Promise<void> | no | — | Called once when the request listener is registered — the precise moment to trigger the target request. | | signal | AbortSignal | no | — | Cancellation. See Runtime constraints for the best-effort semantics. |

RunResult

type RunResult =
  | {
      success: true;
      taskId: string;
      allocatorAddress: string;
      allocatorSignature: string;
      validatorAddress: string;
      validatorSignature: string;
      uHash: string;
      publicFields: unknown[];
    }
  | { success: false; code: ErrorCode; error: string };

On success you get the notary's validatorSignature, the uHash (nullifier hash), publicFields, and the allocator/validator addresses and signatures. On failure, code is a stable ErrorCode and error carries the underlying message.

ErrorCode

Returned in order of the verification steps; the first failing step wins.

| Code | When it happens | |---|---| | MISSING_AES_KEY | aesKeys (aesKey / aesNonce) was not provided. | | INVALID_CONTEXT | Not running inside a Chrome MV3 service worker. | | SCHEMA_FETCH_FAILED | Failed to fetch the schema, or the response was not a valid schema shape. | | SIGNATURE_INVALID | Schema signature verification failed. | | NODE_UNREACHABLE | Failed to allocate a notary node (/sdk/atask; e.g. an invalid appId). | | INTERCEPT_TIMEOUT | No matching request was observed before timeoutMs. | | SESSION_FAILED | Connecting to the notary node / establishing the zkTLS session failed. | | TLS_PROXY_FAILED | 3P-TLS handshake or capture-replay failed. | | PROOF_COMPUTE_FAILED | Local circuit / proof generation failed (includes WASM initialization). | | NODE_VERIFY_FAILED | Node interaction failed (VOLE pairing / param upload / signature evaluation). | | PROOF_GENERATION_FAILED | Other / uncategorized proof-body error (fallback — inspect error). | | ABORTED | Cancelled by the caller's AbortSignal. |

STATUS_MSG

A frozen record of progress strings reported through onStatus. Use the constants rather than hard-coding the literal text so your logic survives wording changes:

import { STATUS_MSG } from '@zkpass/transgate-extension-sdk';

onStatus: (msg) => {
  if (msg === STATUS_MSG.WAITING_MATCH) { /* listener is up */ }
}

Keys include WAITING_MATCH, ALL_API_MATCHED, CONNECTING_NODE, SESSION_ESTABLISHED, INIT_WASM, WASM_INITIALIZED, STARTING_3P_TLS, SETTING_VOLE, GENERATING_CIRCUIT, BUILDING_CIRCUIT, EVALUATING_CIRCUIT, SENDING_HTTP2, GENERATING_PROOF, SUBMITTING_PROOF, VERIFICATION_COMPLETE.

VERSION

import { VERSION } from '@zkpass/transgate-extension-sdk'; // e.g. '0.1.0'

Runtime constraints

  1. Notary node network access. During runZKTLS the SDK opens a TLS connection to schema.nodeHost; this must be covered by host_permissions: ["<all_urls>"].
  2. WASM is inlined into the bundle (no separate asset / path coordination), which increases size (see Bundle size).
  3. AbortSignal is best-effort. WASM computation cannot be interrupted mid-call; cancellation is checked between phases.
  4. No hang without signal/timeoutMs. The default 2-minute timeout applies; a timeout returns INTERCEPT_TIMEOUT.
  5. chrome.webRequest is observe-only. No blocking is performed under MV3.

Bundle size

dist/index.js is roughly 12 MB (gzip ≈ 5.4 MB). The bulk comes from the zkTLS WASM and DOM-parsing dependencies — an inherent cost of the verification logic, not avoidable overhead.

Building from source

Contributing to or building the SDK itself? See docs/building.md for prerequisites, build, packaging & publishing, regenerating the inline WASM, scripts, and CI.

License

See LICENSE.