docs/channels/nostr.md
Status: Optional bundled plugin (disabled by default until configured).
Nostr is a decentralized protocol for social networking. This channel enables OpenClaw to receive and respond to encrypted direct messages (DMs) via NIP-04.
Current OpenClaw releases ship Nostr as a bundled plugin, so normal packaged builds do not need a separate install.
openclaw onboard) and openclaw channels add still surface
Nostr from the shared channel catalog.openclaw plugins install @openclaw/nostr
Use the bare package to follow the current official release tag. Pin an exact version only when you need a reproducible install.
Use a local checkout (dev workflows):
openclaw plugins install --link <path-to-local-nostr-plugin>
Restart the Gateway after installing or enabling plugins.
openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY"
openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY" --relay-urls "wss://relay.damus.io,wss://relay.primal.net"
Use --use-env to keep NOSTR_PRIVATE_KEY in the environment instead of storing the key in config.
# Using nak
nak key generate
{
channels: {
nostr: {
privateKey: "${NOSTR_PRIVATE_KEY}",
},
},
}
export NOSTR_PRIVATE_KEY="nsec1..."
| Key | Type | Default | Description |
|---|---|---|---|
privateKey | string | required | Private key in nsec or hex format |
relays | string[] | ['wss://relay.damus.io', 'wss://nos.lol'] | Relay URLs (WebSocket) |
dmPolicy | string | pairing | DM access policy |
allowFrom | string[] | [] | Allowed sender pubkeys |
enabled | boolean | true | Enable/disable channel |
name | string | - | Display name |
profile | object | - | NIP-01 profile metadata |
Profile data is published as a NIP-01 kind:0 event. You can manage it from the Control UI (Channels -> Nostr -> Profile) or set it directly in config.
Example:
{
channels: {
nostr: {
privateKey: "${NOSTR_PRIVATE_KEY}",
profile: {
name: "openclaw",
displayName: "OpenClaw",
about: "Personal assistant DM bot",
picture: "https://example.com/avatar.png",
banner: "https://example.com/banner.png",
website: "https://example.com",
nip05: "[email protected]",
lud16: "[email protected]",
},
},
},
}
Notes:
https://.allowFrom can DM.allowFrom: ["*"]).Enforcement notes:
{
channels: {
nostr: {
privateKey: "${NOSTR_PRIVATE_KEY}",
dmPolicy: "allowlist",
allowFrom: ["npub1abc...", "npub1xyz..."],
},
},
}
Accepted formats:
nsec... or 64-char hexallowFrom): npub... or hexDefaults: relay.damus.io and nos.lol.
{
channels: {
nostr: {
privateKey: "${NOSTR_PRIVATE_KEY}",
relays: ["wss://relay.damus.io", "wss://relay.primal.net", "wss://nostr.wine"],
},
},
}
Tips:
ws://localhost:7777).| NIP | Status | Description |
|---|---|---|
| NIP-01 | Supported | Basic event format + profile metadata |
| NIP-04 | Supported | Encrypted DMs (kind:4) |
| NIP-17 | Planned | Gift-wrapped DMs |
| NIP-44 | Planned | Versioned encryption |
# Start strfry
docker run -p 7777:7777 ghcr.io/hoytech/strfry
{
channels: {
nostr: {
privateKey: "${NOSTR_PRIVATE_KEY}",
relays: ["ws://localhost:7777"],
},
},
}
wss:// (or ws:// for local).enabled is not false.allowlist for production bots.