Nostr
Status: Optional plugin (disabled by default).
Nostr is a decentralized protocol for social networking. This channel enables OpenClaw to receive and respond to encrypted direct messages (DMs) via NIP-04.
Install (on demand)
Section titled “Install (on demand)”Onboarding (recommended)
Section titled “Onboarding (recommended)”- Onboarding (
openclaw onboard) andopenclaw channels addlist optional channel plugins. - Selecting Nostr prompts you to install the plugin on demand.
Install defaults:
- Dev channel + git checkout available: uses the local plugin path.
- Stable/Beta: downloads from npm.
You can always override the choice in the prompt.
Manual install
Section titled “Manual install”openclaw plugins install @openclaw/nostrUse 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