hashsigs-ts: a WOTS+ library whose install line and package name disagree
Hash-based signatures in typescript, WOTS+
At a glance
- What is it?
- hashsigs-ts is a small TypeScript implementation of WOTS+, the Winternitz One-Time Signature Plus, bundled with tsup, tested with Vitest, and offered under AGPL-3.0-or-later. The gaps matter more than the size: the documented install command does not match the package name in the manifest, and no exported symbol is named anywhere in the documentation.
- Who is it for?
- Use hashsigs-ts if you need WOTS+ in a TypeScript build and are willing to read src/ to learn the exported names, since the documentation names none of them. Before you depend on it, resolve the install by the manifest name rather than the README line, confirm the AGPL-3.0-or-later terms with whoever owns licensing at your organization, and pin the commit hash, because there are no releases and the version is 0.1.0.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 109 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- QuipNetwork/hashsigs-ts11,182 ★ · -9
| Repository | 2026-09-22 | 2026-11-13 |
|---|---|---|
| QuipNetwork/hashsigs-ts | 11.2k | 11.2k |
-9 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The install line says hashsigs-ts and the manifest says @quip.network/hashsigs
Three names describe one project and they do not agree. The repository is hashsigs-ts. The manifest names the package @quip.network/hashsigs at version 0.1.0. The installation line in the documentation is unscoped:
npm install hashsigs-tsSo the command a reader is told to run does not match the name in package.json. Following it verbatim either fails to resolve or installs something that is not this code, and the failure shows up at install time rather than deep inside a build, which at least makes it a cheap lesson. The reliable move is to trust the manifest name and scope the install yourself.
The surrounding identity details point the same way. The copyright line reads Copyright (C) 2024 quip.network while the repository owner is QuipNetwork, and the author field names an individual rather than an organization. Repository metadata records no project homepage, yet the manifest points its own homepage field at the GitHub readme. None of this blocks an install, but it means the package you depend on cannot be confirmed from the documentation alone.
Two test scripts hold the same command, and clean needs a Unix shell
Vitest is the test runner and three scripts drive it. The documentation presents them as running tests once, running tests in watch mode, and running tests with coverage. The manifest shows what is actually bound to each name:
npm testnpm run test:watchnpm run coverageThe first two resolve to the identical string, vitest, with no argument that separates a single run from a watch loop. Only the coverage script appends run and the coverage flag. So the documented split between running once and watching is not encoded in the scripts at all; it depends on how the runner behaves in the environment you happen to be in, which is an assertion rather than a configuration. A contributor on an unfamiliar machine discovers the difference by trying it.
The clean script is where portability bites. It is written as rm -rf dist coverage node_modules, which needs a Unix style shell. In a Windows command prompt or PowerShell that string removes nothing, so a stale build output survives a clean attempt and you debug output that was never rebuilt.
The bundler, the compiler, and the test runner are runtime dependencies
Four of the five entries under dependencies exist to build or test rather than to run: tsup as the bundler, typescript as the compiler, vitest as the test runner, and the Node type definitions. Only the coverage provider sits in devDependencies. So anyone who installs @quip.network/hashsigs pulls a bundler, a compiler, and a test framework into their tree as ordinary runtime dependencies, and their lockfile grows with tools they never invoke.
The reason is visible in how the repository is meant to be worked on. Contributors install the project with npm install, which resolves dependencies, and the documentation treats building and testing as normal local steps rather than as a separate developer only setup. Keeping one list removes a distinction, and the bill arrives downstream with anyone who only wanted the signature code. No note in the documentation explains this arrangement, so it is not a tradeoff you can weigh before depending on the package. The manifest is the place to look, and the prose does not repeat what is in it.
Three entry points from tsup, and no exports map bounding them
The build script is tsup, and the manifest declares three entry points: main pointing at dist/index.js, module at dist/index.mjs, and types at dist/index.d.ts. That is a CommonJS entry, an ES module entry, and a declaration file, which lets both module systems resolve the package and keeps types working for TypeScript consumers.
npm run buildWhat the manifest does not declare is an exports map. Without one there is no allowlist of subpaths, so nothing in the package records which names inside dist are public and which are internal. Publishing is narrowed to the dist directory alone, which keeps test files and TypeScript sources out of the tarball, but narrowing the files does not narrow the API. The consequence for a reader is that the public surface has to be recovered from the built output or the type declarations, and neither the documentation nor any example enumerates one exported function, option, or return type. If you cannot see the signature names, you cannot tell whether what you need is exposed at all.
npm run dev only rebuilds, because a library has nothing to launch
The development script is the bundler in watch mode:
npm run devThe documentation calls this watch mode during development, which is accurate and also easy to misread. For a library there is no server to start and no page to reload, so what you get is a rebuild on every saved file and nothing else. Nothing in your program re-executes, and no caller picks up the new output unless some other process is watching dist.
The tree explains why there is nothing more to run. The top level holds .gitignore, COPYING, README.md, package.json, src/, test/, tsconfig.json, tsup.config.ts, and vitest.config.ts. There is no examples directory, no benchmark, no demo app, and no fixture server. The consequence is that exercising the library means writing your own harness against whatever the build emits, and the documentation never names the hash function, the WOTS+ parameter set, or a single exported symbol. No specification is cited by number either, so there is no external document to read alongside the code.
Coverage gates at 80% on three metrics, and lines are not among them
The project states minimum coverage thresholds of 80% for functions, 80% for branches, and 80% for statements, and asks contributors to meet them before opening a pull request. Three metrics are named and the fourth, line coverage, is not among them. That is a small omission with a practical effect: a change can clear all three stated floors while still leaving lines unexecuted, and nothing written down says whether that passes.
All of it is produced by the single coverage command, which emits four outputs: a console summary, an HTML report written to ./coverage/index.html, a JSON report, and an LCOV report intended for CI consumption. Only the HTML path is given, so the location of the other three has to be discovered from a run. Whether missing thresholds block a merge is not stated anywhere, and no CI workflow is described. The contributing steps stop at opening a pull request, so the enforcement point, if one exists, sits outside what is documented. Budget for reading vitest.config.ts yourself before assuming the gate will catch an untested path.
AGPL-3.0-or-later at 0.1.0, with no release to pin against
The license is the GNU Affero General Public License, version 3 or later, given as SPDX-License-Identifier: AGPL-3.0-or-later in the license section and as the same identifier in the manifest, with a COPYING file at the top level. For a signing library that is a decision a consuming team accepts deliberately rather than discovers later, and the documentation offers no alternative license and no note about who may grant one.
Version is the other half. 0.1.0 is the only version identifier anywhere in the tree, and the repository publishes no GitHub releases, so there is no tag, no changelog entry, and no upgrade path to follow. The manifest is marked for public publishing and its keywords name post-quantum and hash based signatures, so distribution rather than private vendoring is the intent.
The practical consequence is that you consume a moving 0.1.0 by hand. The last push to the repository was July 27, 2026, so work is still landing, but with no releases you cannot tell whether a given change reached any published version. Pin the commit hash if you need reproducibility.
Editorial conclusion
Use hashsigs-ts if you need WOTS+ in a TypeScript build and are willing to read src/ to learn the exported names, since the documentation names none of them. Before you depend on it, resolve the install by the manifest name rather than the README line, confirm the AGPL-3.0-or-later terms with whoever owns licensing at your organization, and pin the commit hash, because there are no releases and the version is 0.1.0.
Frequently asked questions
What is a hash signature in hashsigs-ts?
hashsigs-ts is a hash-based signature implementation in TypeScript featuring WOTS+, the Winternitz One-Time Signature Plus, published as @quip.network/hashsigs and built on the @noble/hashes library.
How do I install hashsigs-ts?
The documented command is npm install hashsigs-ts, but the manifest names the package @quip.network/hashsigs at version 0.1.0. Confirm which name actually resolves before installing.
What license is hashsigs-ts under?
AGPL-3.0-or-later. The SPDX identifier appears in both the license section and the manifest, a COPYING file sits at the top level, and the copyright line reads Copyright (C) 2024 quip.network.
Does hashsigs-ts publish releases?
No. The repository has no GitHub releases, and the manifest sits at version 0.1.0, so there is no tag or changelog to pin a dependency against.
How do I run the tests for hashsigs-ts?
The project uses Vitest with npm test, npm run test:watch, and npm run coverage, and asks contributors to hit 80% minimum coverage on functions, branches, and statements before submitting.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/quipnetwork-hashsigs-ts)Star history chart for your README
[](https://hysenlabs.com/projects/quipnetwork-hashsigs-ts)Was this useful?