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

open-secrets-sdk

v0.1.3

Published

SDK for the Open Secrets protocol on Nostr

Readme

Open Secrets SDK

A decentralized protocol for anonymous confessions, built on Nostr.

Our Philosophy

Confession websites are ephemeral. They start empty, grow briefly, and eventually die, taking years of human secrets and community with them.

Open Secrets was created to end this cycle. By moving the "database" of secrets to a decentralized network (Nostr), we ensure that:

  • Communities Never Die: If your favorite confession site goes offline, the data remains. A new client can spin up and instantly restore the entire community history.
  • Global Repository: We are building a permanent, global archive of anonymous human experiences that no single entity owns or can delete.
  • Cross-App discovery: A secret posted on one app can be discovered and discussed on another, creating a massive, interconnected network of anonymous talk.

Installation

npm install open-secrets-sdk

Usage

Creating a Post

import { createOpenSecretsTags } from 'open-secrets-sdk';

const tags = createOpenSecretsTags({
  lang: 'en',
  gender: 'female',
  age: 25,
  country: 'US',
  client: 'my-awesome-app'
});

// Use with nostr-tools to sign and publish

Parsing metadata

import { parseOpenSecretsTags } from 'open-secrets-sdk';

const metadata = parseOpenSecretsTags(event.tags);
console.log(metadata.gender); // 'female'

Building a Client

The SDK provides an OpenSecrets class that handles the pool management and parsing for you.

Plug-and-Play Example

import { OpenSecrets } from 'open-secrets-sdk';

// 1. Initialize with your relays
const os = new OpenSecrets(['wss://nos.lol', 'wss://relay.damus.io']);

async function main() {
  // 2. Fetch secrets (already parsed and tagged)
  const secrets = await os.fetchSecrets(50);
  
  // 3. Display and filter
  secrets.forEach(s => {
    console.log(`${s.meta.gender} from ${s.meta.country}: ${s.content}`);
  });

  // 4. Publish a new secret (creates and signs an ephemeral event)
  await os.publishSecret("I love decentralized protocols", {
    gender: 'male',
    country: 'DE',
    client: 'my-app'
  });
}

Moderation & Safety

The Decentralized Reality

Because Open Secrets is decentralized, no one can delete a post from the network once it is published. There is no central admin who can "wipe" undesirable content.

Client-Side Defense (The "Gatekeeper" Role)

As a client developer, you are the editor of your own app. You have the power (and responsibility) to decide what your users see.

Since you cannot censor the protocol, you must filter the view.

1. NSFW Handling

Always check the isNsfw flag on the metadata. You can choose to blur these posts or hide them entirely by default.

const postsToShow = allPosts.filter(p => !p.metadata.isNsfw);

2. Content Removals (Reporting)

Since every post uses a fresh identity, blacklisting users is impossible. However, you can maintain a local list of problematic event.ids (e.g., from reports) to hide specific posts that violate your app's rules.

const REMOVED_IDS = ['event_id_1', 'event_id_2'];
const filteredPosts = posts.filter(p => !REMOVED_IDS.includes(p.id));

3. Trust-Based Filtering (Client Allowlist)

If you want to be stricter, you can choose to only display posts that originated from "trusted" clients.

Note on Trusted Clients: Some client may use a "publish first, moderate later" approach to ensure a 100% censorship-resistant archive. This means a trusted client will still broadcast everything to Nostr, but will hide problematic posts in its own UI once its filters catch up. As a developer, you should always combine client trust with your own local filters.

const TRUSTED_CLIENTS = ['lapregunta', 'trusted-app-1'];
const verifiedPosts = posts.filter(p => TRUSTED_CLIENTS.includes(p.metadata.client));

3. Content Filtering

Since it's anonymous text, you can run simple keyword filters before rendering the content to the user.

const BAD_WORDS = ['...'];
const safePosts = posts.filter(p => !BAD_WORDS.some(word => p.content.includes(word)));

Protocol Details

Open Secrets uses Nostr Kind 1 events with specific tags:

  • #t: open-secrets (The gatekeeper tag)
  • #l: Used for namespaced metadata (gender, age, country, lang, etc.)
  • client: Identifies the originating application.
  • content-warning: Standard Nostr tag for NSFW content.

License

MIT