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

ed-sig-http

v0.2.0

Published

Ed25519 signatures for HTTP messages — a narrow profile of RFC 9421.

Readme

ed-sig-http (TypeScript)

Ed25519 signatures for HTTP messages — a narrow profile of RFC 9421.

This package is the TypeScript reference implementation of the signed-calls profile used by MoltWeb agents (spec §4). It is deliberately generic: nothing in the library mentions MoltWeb by name. The consuming application provides the identity header name, identity value, and the public-key resolver; the library handles signing and verification.

Runs in Node 20+, Deno (including Val Town), and modern browsers.

Status

Pre-release. Published under the dummy name ed-sig-http for early development. The API is expected to stabilize through use inside the MoltWeb registry and the tutorial suite; a rebrand and a 1.0 release will follow. Until then, pin to an exact version in production.

What it is

  • An Ed25519-only HTTP Message Signatures library.
  • Implements exactly the covered components the MoltWeb profile needs: @method, @target-uri, @authority, content-digest (when body present), plus a caller-configured identity header.
  • Timestamp window, nonce replay protection, keyid pinning.
  • Pluggable PublicKeyResolver and NonceCache interfaces.

What it is not

  • A general RFC 9421 implementation. No ECDSA, no RSA, no HMAC, no arbitrary covered-component selection.

Install

npm install ed-sig-http

In Deno / Val Town, import from esm.sh:

import { sign, verify } from "https://esm.sh/[email protected]";

Usage

Signing

import { sign } from "ed-sig-http";

const signed = await sign({
  request: {
    method: "POST",
    url: "https://pricer.example.com/quote",
    body: JSON.stringify({ product: "Sony WH-1000XM5" }),
    headers: { "Content-Type": "application/json" },
  },
  privateKey: "z...", // multibase-encoded Ed25519 private key
  publicKey: "z...",  // multibase-encoded Ed25519 public key
  identityHeader: "MoltWeb-Identity",
  identity: "moltweb:shopper-bot",
});

// signed.headers now has Signature-Input, Signature, Content-Digest,
// and MoltWeb-Identity set. Pass them to your HTTP client.
await fetch(signed.url, {
  method: signed.method,
  headers: signed.headers,
  body: signed.body,
});

Verifying

import { verify, type PublicKeyResolver } from "ed-sig-http";

const resolver: PublicKeyResolver = {
  async resolve(identity: string): Promise<string> {
    // Hit a registry, read a cache, query a local table —
    // whatever. Return the public key in multibase form.
    const res = await fetch(`https://moltweb.app/.well-known/moltweb/id/${handleFrom(identity)}`);
    return (await res.json()).public_key;
  },
};

// In your request handler:
const headers: Record<string, string> = {};
for (const [k, v] of req.headers) headers[k] = v;

const result = await verify({
  request: {
    method: req.method,
    url: req.url,
    headers,
    body: await req.text(),
  },
  resolver,
  identityHeader: "MoltWeb-Identity",
});

if (!result.ok) {
  return new Response(JSON.stringify({ reason: result.reason }), { status: 401 });
}

// result.identity is the verified caller.
// result.keyid is their public key, ready for per-caller policy.

Failure reasons

result.reason is a stable, machine-readable string:

missing_headers · malformed_signature_input · signature_label_mismatch
missing_parameter · unsupported_algorithm · timestamp_outside_window
content_digest_not_covered · content_digest_covered_without_body
content_digest_mismatch · identity_not_covered · keyid_mismatch
nonce_replay · malformed_signature · signature_verify_error
signature_invalid · uncovered_component_missing

New reasons will only be added, never removed or renamed. Resolver failures throw rather than returning a VerifyResult — they indicate infrastructure problems, not caller errors.

Pluggable nonce cache

The default InMemoryNonceCache is suitable for single-process deployments (Val Town, a single worker process, tests). For multi-worker production setups, implement the NonceCache interface:

import type { NonceCache } from "ed-sig-http";

class RedisNonceCache implements NonceCache {
  async checkAndStore(identity: string, nonce: string, timestamp: number): Promise<boolean> {
    const key = `nonce:${identity}:${nonce}`;
    const set = await redis.set(key, String(timestamp), { EX: 300, NX: true });
    return set === "OK";
  }
}

await verify({ request, resolver, identityHeader }, { nonceCache: new RedisNonceCache() });

Testing

npm install
npm test

Tests validate against /packages/test-vectors/v0.1.json — the same vectors the PHP package must satisfy. If these fail, either the library has a bug or the vectors are stale.

License

Apache-2.0.