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

nostr-succession

v0.2.0

Published

Key succession for Nostr: a pre-committed migration key you never store, a successor that consents, and a client rule for when contacts follow on their own. Kinds 1360 and 1361.

Readme

nostr-succession

CI npm licence: MIT GitHub Sponsors

A key that can change, with a commitment made before it had to.

Two regular kinds. 1360 is a pre-commitment: the identity names one migration key, in advance and in public, so a thief who steals today's key cannot also invent the move. 1361 is the migration: the migration key names a successor, the successor signs its consent, and an optional linkage proof, signed by the root's holder, vouches for the successor as the root's own.

The migration key is meant to be derived from the root (nsec-tree purpose migration, index 0) and never stored; the library checks none of that, because it cannot. Any key the identity names is the migration key. The identity is a child of that root, never the root itself, or the commitment protects nothing.

import { buildPrecommit, buildMigration, validateMigration, decide } from 'nostr-succession'

// Day one: commit, and never think about it again.
publish(buildPrecommit(identityPrivateKey, migrationPub))

// The day it must move.
const m = buildMigration({ precommit, migrationPrivateKey, successorPrivateKey, linkage })

// A client deciding whether to follow on its own.
const v = validateMigration(m, precommit)          // consent verified, or a reason
const d = decide(m, precommit, { precommitFirstSeen, migrationFirstSeen, identityRoot, bondedSuccessor })
// d.path is 'automatic' or 'manual', d.because says why, and the words shown come from that

decide is never automatic on consent alone. It follows when the pre-commitment demonstrably predates the migration by seven days, measured against the earlier of the migration's created_at and this client's own first sight of it. "Demonstrably" means this client's own first-seen of the pre-commitment, or an OpenTimestamps attestation, and the seven-day gap applies to both: an attestation an hour old proves existence, not precedence. It also follows when the successor shares a root that was bound to the identity seven days earlier (the master on the identity's own first published linkage proof, kept for ever and never replaced), when a bond ceremony confirmed the named successor, or when someone the user trusts attested to the named successor. A second pre-commitment or a second migration by the same key makes everything manual, including the first.

validateMigration refuses more than it accepts: the migration key must differ from the identity, the successor must be a key that is neither, every tag must appear exactly once (linkage at most once), hex must be lower case, created_at must be a safe non-negative integer, and the signature is always re-verified rather than trusted from a cache.

Vectors in vectors/succession.json are the draft's known-answer file: fourteen cases, each with the client's own first sight of both events, including a hijack by a holder of the migration key, a second migration by the same key, an OpenTimestamps attestation both old and fresh, a future-dated migration, a fresh root binding and a contested identity. verifier/verify.mjs is a second implementation of the same rules, written from the draft's text and kept apart from the library's code; npm test runs both over the vectors and they must agree on every case.

decide also refuses a first-seen time that is not in seconds (a millisecond timestamp would hand the decision to the signer's own date), a first-seen time later than now when now is given, and a root binding to the identity's own key or the migration key, which protect nothing. Its verdict names the identity and successor it is about, and an optional expected identity makes a mismatch manual. evidenceFrom derives the contested and secondMigration flags from fetched events by distinct id, so two clients count the same way.

What remains

In the profile's own words, from its table of what can be compelled: a developer can still be pressured; the code and the network do not depend on them. A published succession makes losing the maintainer maintenance, not extinction, and nothing here stops anyone pressuring whoever holds the migration key today. The seven-day rule buys the owner a week to contest a move, not immunity from one.

Licence

MIT. ForgeSworn.