openclaw-ndr
v0.0.3
Published
OpenClaw channel plugin for nostr-double-ratchet (forward-secure E2E encryption)
Downloads
78
Maintainers
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 onboardwalks you through setup - Group chats - NDR group fan-out 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-ndrFrom a local clone:
git clone https://github.com/mmalmi/openclaw-ndr
openclaw plugins install -l ./openclaw-ndrSetup
Run the interactive onboarding:
openclaw onboardSelect the NDR channel when prompted. The onboarding will:
- Check if
ndrCLI is installed - Ask you to paste a chat invite URL from chat.iris.to
- Accept the invite and send a hello message
- Configure your owner pubkey (so only you can control the agent)
Getting a chat invite URL
- Go to chat.iris.to
- Click the + (New Chat) button
- Click Copy your chat link
- Paste it into the onboarding prompt
Start the gateway
openclaw gateway runConfiguration
The onboarding writes config to ~/.openclaw/openclaw.json. You can also edit it manually:
{
channels: {
ndr: {
// Owner's pubkey - only messages from this npub 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). Can be an array or a map.
groups: ["11111111-1111-1111-1111-111111111111"]
}
}
}Authorization:
- Only messages from
ownerPubkeyare handled as agent commands - Messages from other pubkeys are logged but ignored
- If
ownerPubkeyis not set, all messages are handled
Usage
Check channel status
openclaw channels status --channel ndrList active chats
ndr chat listGroups (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 are not auto-accepted; if the inviter matches ownerPubkey, the
plugin auto-accepts, otherwise it notifies the owner 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
- Listening - Runs
ndr listento receive incoming messages - Receiving - Decrypts messages using the double ratchet session
- Sending - Uses
ndr sendto encrypt and publish messages - Session management - ndr handles key rotation automatically
- Groups -
ndr groupfan-out 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-cliMedia attachments not working
Make sure hashtree-cli is installed: hashtree-cli --version
"Failed to send message"
Check that:
- You have an active chat session with the recipient
- The relay is reachable
- ndr CLI is working:
ndr chat list
Group messages not showing up
Check that:
groupPolicyisopen(default) orallowlistwith a matchinggroupAllowFrom- The group ID is included in
groupsif you configured a group allowlist - Your NDR client is in the group and has accepted it
