> ## 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.

# Nostr Channel

> Decentralized messaging via Nostr relays

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:

```bash theme={null}
# Install nak (Go required)
go install github.com/fiatjaf/nak@latest

# Verify installation
nak --version
```

See [nak documentation](https://github.com/fiatjaf/nak) for more installation options.

## Configuration

Add Nostr to your `config.json`:

```json theme={null}
{
  "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

<ParamField path="private_key" type="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.
</ParamField>

<ParamField path="owner_pubkey" type="string" required>
  Public key of the bot owner (you). Only this pubkey can send DMs to the bot.

  Formats:

  * npub-encoded: `"npub1..."`
  * Hex: `"abc123..."`
</ParamField>

<ParamField path="relays" type="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`
</ParamField>

<ParamField path="nak_path" type="string" default="nak">
  Path to the `nak` binary. Use absolute path if not in `$PATH`.
</ParamField>

<ParamField path="account_id" type="string" default="default">
  Account identifier for multi-account setups
</ParamField>

## Setup Guide

<Steps>
  <Step title="Install nak">
    ```bash theme={null}
    # Install via Go
    go install github.com/fiatjaf/nak@latest

    # Verify installation
    nak --version
    ```

    Ensure `$GOPATH/bin` is in your `$PATH`.
  </Step>

  <Step title="Generate or Import Keys">
    **Generate new keys:**

    ```bash theme={null}
    # 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.
  </Step>

  <Step title="Convert Keys to Required Formats">
    ```bash theme={null}
    # Convert nsec to hex (for private_key)
    nak key convert <nsec1...>

    # Convert hex to npub (for owner_pubkey)
    nak key public <hex_private_key>
    ```
  </Step>

  <Step title="Store Private Key Securely">
    **Option 1: Encrypted secret (recommended)**

    ```bash theme={null}
    nullclaw secrets set nostr_key
    # Paste your private key when prompted
    ```

    Then use in config:

    ```json theme={null}
    {
      "private_key": "secret:nostr_key"
    }
    ```

    **Option 2: Direct in config (development only)**

    ```json theme={null}
    {
      "private_key": "nsec1..."
    }
    ```
  </Step>

  <Step title="Configure NullClaw">
    Add Nostr to `~/.nullclaw/config.json`:

    ```json theme={null}
    {
      "channels": {
        "nostr": {
          "accounts": {
            "main": {
              "private_key": "secret:nostr_key",
              "owner_pubkey": "npub1...",
              "relays": [
                "wss://relay.damus.io",
                "wss://nos.lol",
                "wss://relay.nostr.band"
              ]
            }
          }
        }
      }
    }
    ```
  </Step>

  <Step title="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.
  </Step>
</Steps>

## NIP-17 vs NIP-04

### NIP-17 (Gift Wrap) — Recommended

**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)

```json theme={null}
{
  "private_key": "nsec1abc123..."
}
```

Never commit plaintext keys to version control.

### Encrypted Secrets (Production)

```bash theme={null}
nullclaw secrets set nostr_key
```

Config:

```json theme={null}
{
  "private_key": "secret:nostr_key"
}
```

### Remote Signer (Advanced)

Use Nostr Connect (NIP-46) with a remote signer:

```json theme={null}
{
  "private_key": "bunker://..."
}
```

This keeps your private key on a separate device/service.

## Relay Selection

### Recommended Relay Sets

**General purpose:**

```json theme={null}
{
  "relays": [
    "wss://relay.damus.io",
    "wss://nos.lol",
    "wss://relay.nostr.band"
  ]
}
```

**Privacy-focused:**

```json theme={null}
{
  "relays": [
    "wss://nostr.wine",
    "wss://relay.snort.social"
  ]
}
```

**Regional:**

```json theme={null}
{
  "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`:
   ```bash theme={null}
   export PATH="$PATH:$GOPATH/bin"
   ```
3. Use absolute path in config:
   ```json theme={null}
   {
     "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](https://nostr.watch)
3. Check firewall/proxy settings
4. Verify relay supports WebSocket secure (wss\://)

### Key Conversion Issues

```bash theme={null}
# 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`
