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

openclaw-ndr

v0.0.15

Published

OpenClaw channel plugin for nostr-double-ratchet (forward-secure E2E encryption)

Readme

openclaw-ndr

OpenClaw channel plugin for nostr-double-ratchet - forward-secure end-to-end encrypted messaging over Nostr.

Compatible with chat.iris.to.

Features

  • Forward secrecy - Past messages remain secure even if keys are compromised
  • Double ratchet encryption - Based on Signal's proven protocol
  • Nostr transport - Messages sent via Nostr relays
  • Interactive onboarding - openclaw onboard walks you through setup
  • Group chats - Native NDR group transport with shared-channel invites

Prerequisites

Install Rust and the required CLIs:

curl -sSf https://sh.rustup.rs | sh && cargo install ndr hashtree-cli
  • ndr - Required for double ratchet encryption
  • hashtree-cli - Optional, for encrypted media uploads via hashtree

Installation

Note: OpenClaw's plugin system is under active development. These instructions may change.

From GitHub:

openclaw plugins install https://github.com/mmalmi/openclaw-ndr

From a local clone:

git clone https://github.com/mmalmi/openclaw-ndr
openclaw plugins install -l ./openclaw-ndr

Setup

Run the interactive onboarding:

openclaw onboard

Select the NDR channel when prompted. The onboarding will:

  1. Check if ndr CLI is installed
  2. Generate a private pairing link (and QR code)
  3. Wait for you to accept it in chat.iris.to
  4. Configure your owner pubkey automatically from the accepted invite (no manual npub input)
  5. In most cases, you send the first message from chat.iris.to after starting the gateway

Accepting The Pairing Link

  1. Run openclaw onboard and select NDR
  2. Copy the pairing URL printed by the onboarding (or scan the QR)
  3. Open it in your browser (it will take you to chat.iris.to and start the chat)
  4. After you accept, the agent locks to your pubkey automatically
  5. Start openclaw gateway run
  6. Send the first DM from chat.iris.to, then the bot can reply

Start the gateway

openclaw gateway run

Configuration

The onboarding writes config to ~/.openclaw/openclaw.json. You can also edit it manually:

{
  channels: {
    ndr: {
      // Owner's pubkey (npub or hex) - only messages from this key are handled as commands
      ownerPubkey: "npub1...",

      // Optional: Nostr relays (defaults shown below)
      relays: [
        "wss://temp.iris.to",
        "wss://relay.snort.social",
        "wss://relay.primal.net",
        "wss://relay.damus.io",
        "wss://offchain.pub"
      ],

      // Optional: Path to ndr CLI (default: "ndr" in PATH)
      ndrPath: "/path/to/ndr",

      // Optional: Custom data directory for ndr (default: ~/.openclaw/ndr-data)
      dataDir: "~/.openclaw/ndr-data",

      // Optional: Group policy ("open" | "allowlist" | "disabled")
      groupPolicy: "open",

      // Optional: Allowed senders in groups (npub/hex, "*" allows anyone)
      groupAllowFrom: ["npub1...", "abcdef..."],

      // Optional: Allowed group IDs (UUIDs). When set, only listed groups are handled.
      groups: ["11111111-1111-1111-1111-111111111111"]
    }
  }
}

Authorization:

  • Only messages from ownerPubkey are handled as agent commands
  • Messages from other pubkeys are logged but ignored
  • If ownerPubkey is not set, the first accepted invite/contact is locked as owner

Usage

Check channel status

openclaw channels status --channel ndr

List active chats

ndr chat list

Release Smoke Tests

Run these before publishing to verify both plugin and cross-app interop.

1) OpenClaw plugin docker e2e (alice <-> bob)

pnpm test:e2e:docker

2) iris-chat interop using local nostr-double-ratchet TS build

This always tests against your local library tree (not the currently published npm version).

# Optional overrides:
# IRIS_CHAT_REPO=~/src/iris-chat
# NDR_TS_REPO=~/src/nostr-double-ratchet/ts
# REPEAT_EACH=8
pnpm test:interop:iris-local-lib

3) dockerized OpenClaw bot + iris-chat seen receipt interop

Runs a real OpenClaw gateway bot in Docker with this plugin and verifies in Playwright that Iris marks the outgoing message as seen. The harness applies a temporary patch to the copied ndr source so listen events use inner rumor IDs for receipts.

# Optional overrides:
# IRIS_CHAT_REPO=~/src/iris-chat
# NDR_REPO=~/src/nostr-double-ratchet
# OPENCLAW_REPO=~/src/openclaw
# RELAY_URL=wss://temp.iris.to
pnpm test:e2e:iris-seen

Groups (NDR)

NDR groups are managed by the ndr CLI. This plugin listens for group_message events and can reply in groups when allowed by groupPolicy (default: open). Group invites from ownerPubkey are auto-accepted; other group invites are not auto-accepted and the owner is notified to decide.

# Create a group (members are hex pubkeys)
ndr group create --name "My Group" --members <hex_pubkey,hex_pubkey>

# List groups (get group IDs)
ndr group list

# Send a group message
ndr group send <group_id> "hello"

How it works

  1. Listening - Runs ndr listen to receive incoming messages
  2. Receiving - Decrypts messages using the double ratchet session
  3. Sending - Uses ndr send to encrypt and publish messages
  4. Session management - ndr handles key rotation automatically
  5. Groups - Native ndr group transport with shared-channel invites

Security

  • Forward secrecy - Each message uses a unique encryption key
  • Session isolation - Each chat has its own ratchet state
  • No key exposure - Private keys are managed by the ndr CLI

Troubleshooting

"ndr: command not found" / "hashtree-cli: command not found"

Install both (requires Rust):

curl -sSf https://sh.rustup.rs | sh && cargo install ndr hashtree-cli

Media attachments not working

Make sure hashtree-cli is installed: hashtree-cli --version

"Failed to send message"

Check that:

  1. You have an active chat session with the recipient
  2. The relay is reachable
  3. ndr CLI is working: ndr chat list

Group messages not showing up

Check that:

  1. groupPolicy is open (default) or allowlist with a matching groupAllowFrom
  2. The group ID is included in groups if you configured a group allowlist
  3. Your NDR client is in the group and has accepted it