Nostr
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.
Bundled plugin
Section titled “Bundled plugin”Current OpenClaw releases ship Nostr as a bundled plugin, so normal packaged builds do not need a separate install.
Older/custom installs
Section titled “Older/custom installs”- Onboarding (
openclaw onboard) andopenclaw channels addstill surface Nostr from the shared channel catalog. - If your build excludes bundled Nostr, install the npm package directly.
openclaw plugins install @openclaw/nostrUse 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.
Non-interactive setup
Section titled “Non-interactive setup”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.
Quick setup
Section titled “Quick setup”- Generate a Nostr keypair (if needed):
# Using naknak key generate- Add to config:
{ channels: { nostr: { privateKey: "${NOSTR_PRIVATE_KEY}", }, },}- Export the key:
export NOSTR_PRIVATE_KEY="nsec1..."- Restart the Gateway.
Configuration reference
Section titled “Configuration reference”| 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 metadata
Section titled “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", }, }, },}Notes:
- Profile URLs must use
https://. - Importing from relays merges fields and preserves local overrides.
Access control
Section titled “Access control”DM policies
Section titled “DM policies”- pairing (default): unknown senders get a pairing code.
- allowlist: only pubkeys in
allowFromcan DM. - open: public inbound DMs (requires
allowFrom: ["*"]). - disabled: ignore inbound DMs.
Enforcement notes:
- Inbound event signatures are verified before sender policy and NIP-04 decryption, so forged events are rejected early.
- Pairing replies are sent without processing the original DM body.
- Inbound DMs are rate-limited and oversized payloads are dropped before decrypt.
Allowlist example
Section titled “Allowlist example”{ channels: { nostr: { privateKey: "${NOSTR_PRIVATE_KEY}", dmPolicy: "allowlist", allowFrom: ["npub1abc...", "npub1xyz..."], }, },}Key formats
Section titled “Key formats”Accepted formats:
- Private key:
nsec...or 64-char hex - Pubkeys (
allowFrom):npub...or hex
Relays
Section titled “Relays”Defaults: 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:
- Use 2-3 relays for redundancy.
- Avoid too many relays (latency, duplication).
- Paid relays can improve reliability.
- Local relays are fine for testing (
ws://localhost:7777).
Protocol support
Section titled “Protocol support”| 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 |
Testing
Section titled “Testing”Local relay
Section titled “Local relay”# Start strfrydocker run -p 7777:7777 ghcr.io/hoytech/strfry{ channels: { nostr: { privateKey: "${NOSTR_PRIVATE_KEY}", relays: ["ws://localhost:7777"], }, },}Manual test
Section titled “Manual test”- Note the bot pubkey (npub) from logs.
- Open a Nostr client (Damus, Amethyst, etc.).
- DM the bot pubkey.
- Verify the response.
Troubleshooting
Section titled “Troubleshooting”Not receiving messages
Section titled “Not receiving messages”- Verify the private key is valid.
- Ensure relay URLs are reachable and use
wss://(orws://for local). - Confirm
enabledis notfalse. - Check Gateway logs for relay connection errors.
Not sending responses
Section titled “Not sending responses”- Check relay accepts writes.
- Verify outbound connectivity.
- Watch for relay rate limits.
Duplicate responses
Section titled “Duplicate responses”- Expected when using multiple relays.
- Messages are deduplicated by event ID; only the first delivery triggers a response.
Security
Section titled “Security”- Never commit private keys.
- Use environment variables for keys.
- Consider
allowlistfor production bots. - Signatures are verified before sender policy, and sender policy is enforced before decrypt, so forged events are rejected early and unknown senders cannot force full crypto work.
Limitations (MVP)
Section titled “Limitations (MVP)”- Direct messages only (no group chats).
- No media attachments.
- NIP-04 only (NIP-17 gift-wrap planned).
Related
Section titled “Related”- Channels Overview — all supported channels
- Pairing — DM authentication and pairing flow
- Groups — group chat behavior and mention gating
- Channel Routing — session routing for messages
- Security — access model and hardening