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

@emilia-protocol/issue

v0.2.0

Published

Zero-dependency local issuance of EP authorization receipts (EP-RECEIPT-v1; I-D draft-schrock-ep-authorization-receipts §6.2), signed locally with your own keys. The signing-side companion to @emilia-protocol/verify: issue locally, verify anywhere. Node b

Readme

@emilia-protocol/issue

Issue locally, verify anywhere.

The signing-side companion to @emilia-protocol/verify. It lets any external developer mint an EP authorization receipt (EP-RECEIPT-v1; I-D draft-schrock-ep-authorization-receipts §6.2) on their own machine, signed with their own keys — then anyone can verify it offline with @emilia-protocol/verify. No EMILIA backend. No account. No API key. Just node:crypto.

Zero runtime dependencies. The whole issuer is one small file you can read in an afternoon.

Install

npm install @emilia-protocol/issue @emilia-protocol/verify

Or run the CLI straight from npx — no install needed.

60-second quickstart

# 1. Generate a local issuer bundle (one approver key + one log key)
npx @emilia-protocol/issue keygen --out issuer-keys.json --log-name acme

# 2. Describe the irreversible action you're authorizing
cat > action.json <<'JSON'
{
  "ep_version": "1.0",
  "action_type": "vendor_bank_account_change",
  "target": { "system": "erp.example", "resource": "vendor/acme" },
  "parameters": { "new_bank_hash": "sha256:9f2c..." },
  "initiator": "ep:entity:ap-agent",
  "policy_id": "ep:policy:vendor-bank-change@v1",
  "requested_at": "2026-06-12T16:00:00Z"
}
JSON

# 3. Issue a signed receipt (+ the public verification material)
npx @emilia-protocol/issue issue \
  --keys issuer-keys.json \
  --action action.json \
  --out receipt.json \
  --verification verification.json

# 4. Verify it offline — anyone, anywhere, with the public material only
node --input-type=module -e '
import { verifyTrustReceipt } from "@emilia-protocol/verify";
import { readFileSync } from "node:fs";
const receipt = JSON.parse(readFileSync("receipt.json", "utf8"));
const v = JSON.parse(readFileSync("verification.json", "utf8"));
const r = verifyTrustReceipt(receipt, { approverKeys: v.approver_keys, logPublicKey: v.log_public_key });
console.log(r.checks, r.valid ? "VERIFIED" : "NOT VERIFIED");
'

Want it in one shot? npx @emilia-protocol/issue demo generates throwaway keys, issues a sample receipt for a sample irreversible action, and verifies it — printing all 7 checks.

Optional: attach an initiator escalation attestation (PIP-007)

One optional extra step. The initiator can attach its own stated reason for asking a human — a structured escalation_trigger, an optional policy_basis rule id, and an optional ≤280-char statement. Because the context is canonicalized whole, the approver's signature automatically covers it: the receipt then proves the stated reason was part of what the approver signed.

# Describe why the initiator escalated (one of: irreversibility, magnitude,
# uncertainty, novelty, authority_gap, policy_rule). policy_basis is required
# whenever a deterministic rule fired (always for policy_rule).
cat > attestation.json <<'JSON'
{
  "escalation_trigger": "irreversibility",
  "policy_basis": "ep:policy:vendor-bank-change@v1",
  "statement": "Vendor bank-account change is irreversible; policy requires a named human approval."
}
JSON

# Pass it to the same issue command — the attestation is copied verbatim into
# every context (identical across all of them for m-of-n approvals).
npx @emilia-protocol/issue issue \
  --keys issuer-keys.json --action action.json --out receipt.json \
  --verification verification.json \
  --attestation attestation.json

The attestation is a claim by the initiator — identified but never trusted. It does not relax any check or raise any trust score; @emilia-protocol/verify's verifyTrustReceipt() surfaces it as an advisory (result.attestation) and flags malformed or cross-context-inconsistent attestations, but never changes signature validity. See PIP-007.

The receipt is an I-D §6.2 authorization receipt, so it's verified with @emilia-protocol/verify's verifyTrustReceipt(receipt, { approverKeys, logPublicKey }) — the full §6.3 algorithm. (The npx @emilia-protocol/verify <file> CLI is for the single-signature EP-RECEIPT-v1 wire format.) verification.json supplies both the approver keys and the log public key, all public.

receipt.json is the portable evidence artifact. verification.json carries the public approver key entry and the log public key a verifier needs. Keep issuer-keys.json secret — it holds private keys.

Library quickstart

import { generateIssuerKeyBundle, issueFromKeyBundle } from '@emilia-protocol/issue';
import { verifyTrustReceipt } from '@emilia-protocol/verify';

const keys = generateIssuerKeyBundle({ approverId: 'ep:approver:finance-lead' });

const action = {
  ep_version: '1.0',
  action_type: 'payment.release',
  target: { system: 'treasury.example', resource: 'wire/8841' },
  parameters: { amount: '25000.00', currency: 'USD' },
  initiator: 'ep:entity:agent-recon-7',
  policy_id: 'ep:policy:wires-over-10k@v1',
  requested_at: new Date().toISOString(),
};

const { receipt, verification } = await issueFromKeyBundle({ keys, action });

const result = verifyTrustReceipt(receipt, {
  approverKeys: verification.approver_keys,
  logPublicKey: verification.log_public_key,
});

console.log(result.valid); // true

For multi-approver receipts, separation of duties, or chaining to a prior receipt, drop down to buildContextscollectSignoffsassembleAuthorizationReceipt (or the one-call issueAuthorizationReceipt). See index.d.ts for the full surface.

What a locally-issued receipt proves — and what it does not

Be precise about the claim. A receipt this package issues proves, with offline cryptography and no trust in your logs or in EMILIA:

  • a named key signed off on this exact action (the action hash binds every parameter — change one byte and verification fails);
  • the signoff was made under the stated policy (the context commits to the policy hash);
  • the signoff happened before execution, inside the stated validity window;
  • the receipt is included in a log checkpoint signed by the named log key, so it can't be silently backdated or altered after the fact.

The receipt proves those things. It does not prove that the human is who the key claims to be. Binding a key to a real, identity-proofed person is a separate layer — the Approver Directory plus Class-A device-bound (WebAuthn) signoffs. A Class-B/C software-key signoff (what this CLI issues) proves a key authorized the action; it does not prove a specific enrolled human held that key.

Class-A signoffs are not produced by this CLI. A device-bound WebAuthn assertion (the strongest "a verified human was present" signal) requires EP's hosted ceremony — the issuer never holds the device key. This package issues Class-B/C software-key signoffs and assembles the full receipt around them. If you later add Class-A device signoffs through the ceremony, the same @emilia-protocol/verify checks them too.

In short: issue locally to get the cryptographic crank turning — mint a receipt first, then layer the Approver Directory and Class-A device binding around it for human-identity assurance.

CLI reference

ep-issue keygen --out issuer-keys.json [--approver-id …] [--approver-key-id …] [--log-name acme | --log-key-id ep:log:acme#1]
ep-issue issue  --keys issuer-keys.json --action action.json --out receipt.json [--verification …] [--policy …] [--policy-hash sha256:…] [--receipt-id …] [--expires-in 3600] [--attestation attestation.json]
ep-issue demo

keygen prints the log key id in the canonical ep:log:<name>#1 form. issue writes a complete signed receipt including the Merkle log_proof. --attestation attaches the optional PIP-007 initiator escalation attestation (see above); it is validated against PIP-007 §1 (enum, ≤280-char statement, only the three defined members) and copied verbatim into every context.

Design principles

  • Zero dependencies — only node:crypto. No supply chain risk.
  • Byte-compatible with the verifier — canonicalization, hashing, and the Merkle/checkpoint shapes are identical to @emilia-protocol/verify's reference profile (§6.3), so issued receipts verify 7/7. This is enforced in CI on every push.
  • Delegated signing — the issuer never holds approver keys in its core path; each approver supplies a callback.

License

Apache-2.0