Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nullclaw/nullclaw/llms.txt

Use this file to discover all available pages before exploring further.

The Nostr channel connects NullClaw to the Nostr protocol using NIP-17 (gift-wrapped DMs) and NIP-04 (legacy encrypted DMs) via the nak CLI tool.

Features

  • NIP-17 (Gift Wrap) — Modern private messaging with forward secrecy
  • NIP-04 — Legacy encrypted DMs for backward compatibility
  • Protocol Mirroring — Automatically replies using the same protocol the sender used
  • Multi-Relay Support — Connect to multiple Nostr relays simultaneously
  • Decentralized — No central server, censorship-resistant
  • Key Management — Supports plaintext keys or remote signers (bunker://)
  • Duplicate Suppression — Deduplicates messages across relays

Prerequisites

You must have the nak CLI tool installed:
# Install nak (Go required)
go install github.com/fiatjaf/nak@latest

# Verify installation
nak --version
See nak documentation for more installation options.

Configuration

Add Nostr to your config.json:
{
  "channels": {
    "nostr": {
      "accounts": {
        "main": {
          "private_key": "nsec1...",
          "owner_pubkey": "npub1...",
          "relays": [
            "wss://relay.damus.io",
            "wss://nos.lol",
            "wss://relay.nostr.band"
          ],
          "nak_path": "nak"
        }
      }
    }
  }
}

Configuration Options

private_key
string
required
Your Nostr private key in one of these formats:
  • nsec-encoded key: "nsec1..."
  • Hex key: "abc123..."
  • Bunker URI: "bunker://..."
  • Encrypted secret ID: "secret:nostr_key"
For production, use "secret:nostr_key" and store the key in NullClaw’s secrets backend.
owner_pubkey
string
required
Public key of the bot owner (you). Only this pubkey can send DMs to the bot.Formats:
  • npub-encoded: "npub1..."
  • Hex: "abc123..."
relays
string[]
required
List of Nostr relay URLs (wss:// WebSocket endpoints). Minimum 1, recommended 3-5 for redundancy.Popular relays:
  • wss://relay.damus.io
  • wss://nos.lol
  • wss://relay.nostr.band
  • wss://nostr.wine
  • wss://relay.snort.social
nak_path
string
default:"nak"
Path to the nak binary. Use absolute path if not in $PATH.
account_id
string
default:"default"
Account identifier for multi-account setups

Setup Guide

1

Install nak

# Install via Go
go install github.com/fiatjaf/nak@latest

# Verify installation
nak --version
Ensure $GOPATH/bin is in your $PATH.
2

Generate or Import Keys

Generate new keys:
# Generate new keypair
nak key generate > nostr_key.txt
cat nostr_key.txt
Import existing keys: If you already have a Nostr identity, export your private key from your client.
3

Convert Keys to Required Formats

# Convert nsec to hex (for private_key)
nak key convert <nsec1...>

# Convert hex to npub (for owner_pubkey)
nak key public <hex_private_key>
4

Store Private Key Securely

Option 1: Encrypted secret (recommended)
nullclaw secrets set nostr_key
# Paste your private key when prompted
Then use in config:
{
  "private_key": "secret:nostr_key"
}
Option 2: Direct in config (development only)
{
  "private_key": "nsec1..."
}
5

Configure NullClaw

Add Nostr to ~/.nullclaw/config.json:
{
  "channels": {
    "nostr": {
      "accounts": {
        "main": {
          "private_key": "secret:nostr_key",
          "owner_pubkey": "npub1...",
          "relays": [
            "wss://relay.damus.io",
            "wss://nos.lol",
            "wss://relay.nostr.band"
          ]
        }
      }
    }
  }
}
6

Start NullClaw

Run nullclaw and send a DM to your bot’s npub from a Nostr client (Damus, Amethyst, etc.). You should receive a response.

NIP-17 vs NIP-04

Advantages:
  • Forward secrecy (ephemeral keys)
  • Better metadata privacy
  • Replay protection
  • Modern standard
How it works:
  1. Sender wraps message in ephemeral key encryption
  2. Message published with randomized timestamp
  3. Recipient unwraps using their private key

NIP-04 (Legacy Encrypted DMs)

Advantages:
  • Wider client support
  • Simpler implementation
  • Backward compatibility
Limitations:
  • No forward secrecy
  • Metadata leakage (timestamps, sender/recipient visible)

Protocol Mirroring

NullClaw automatically detects which protocol the sender used and replies with the same protocol:
  • Receive NIP-17 message → Reply with NIP-17
  • Receive NIP-04 message → Reply with NIP-04
This ensures maximum compatibility while preferring modern protocols.

Key Management

Plaintext Keys (Development)

{
  "private_key": "nsec1abc123..."
}
Never commit plaintext keys to version control.

Encrypted Secrets (Production)

nullclaw secrets set nostr_key
Config:
{
  "private_key": "secret:nostr_key"
}

Remote Signer (Advanced)

Use Nostr Connect (NIP-46) with a remote signer:
{
  "private_key": "bunker://..."
}
This keeps your private key on a separate device/service.

Relay Selection

General purpose:
{
  "relays": [
    "wss://relay.damus.io",
    "wss://nos.lol",
    "wss://relay.nostr.band"
  ]
}
Privacy-focused:
{
  "relays": [
    "wss://nostr.wine",
    "wss://relay.snort.social"
  ]
}
Regional:
{
  "relays": [
    "wss://relay.nostr.asia",
    "wss://relay.nostr.au"
  ]
}

Relay Count Considerations

  • Minimum: 1 relay (single point of failure)
  • Recommended: 3-5 relays (good redundancy)
  • Maximum: 10 relays (diminishing returns, increased bandwidth)
More relays = better delivery but higher bandwidth usage.

Access Control

Unlike other channels, Nostr has built-in access control:
  • Only the owner_pubkey can send DMs to the bot
  • All DMs are end-to-end encrypted
  • No additional allowlist needed
To allow multiple users, run multiple Nostr channel instances with different keys.

Duplicate Suppression

When connected to multiple relays, the same message may arrive multiple times. NullClaw automatically deduplicates based on the inner rumor ID (kind:14 event ID), ensuring each unique message is processed only once.

Troubleshooting

nak Command Not Found

  1. Verify installation: which nak
  2. Check $GOPATH/bin is in $PATH:
    export PATH="$PATH:$GOPATH/bin"
    
  3. Use absolute path in config:
    {
      "nak_path": "/home/user/go/bin/nak"
    }
    

Messages Not Received

  1. Verify owner_pubkey matches your actual pubkey
  2. Check relay connections: nak req -k 1 <relay_url>
  3. Ensure sender is using NIP-17 or NIP-04 DMs (not public notes)
  4. Review NullClaw logs: nullclaw --log-level debug
  5. Test relay connectivity: websocat wss://relay.damus.io

Failed to Decrypt

  1. Verify private_key is correct
  2. Check key format (nsec vs hex)
  3. For encrypted secrets: nullclaw secrets get nostr_key
  4. Ensure sender encrypted message to correct pubkey

Relay Connection Errors

  1. Test relay manually: nak req -k 1 wss://relay.damus.io
  2. Try alternative relays from nostr.watch
  3. Check firewall/proxy settings
  4. Verify relay supports WebSocket secure (wss://)

Key Conversion Issues

# nsec → hex
nak key convert nsec1abc123...

# hex → npub
nak key public abc123...

# Extract public key from private key
nak key public $(nak key convert nsec1abc123...)

Source Code

Implementation: src/channels/nostr.zig