Skip to main content
ClaudeWave
Skill128 repo starsupdated 2mo ago

using-nostr

This Claude Code skill enables posting public notes to the Nostr decentralized social network, replying to existing posts, and sending encrypted messages across multiple relays using the nostr-sdk library. Use it when integrating Nostr publishing capabilities into applications that need to broadcast messages, manage social interactions, or interact with Nostr's protocol infrastructure without building relay connections from scratch.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/besoeasy/open-skills /tmp/using-nostr && cp -r /tmp/using-nostr/skills/using-nostr ~/.claude/skills/using-nostr
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# NOSTR Posting Skill
# Using nostr-sdk library
# Source: https://github.com/besoeasy/nostr-sdk

## Overview
Post messages, send encrypted DMs, and interact with the Nostr decentralized social protocol using minimal direct exports from the `nostr-sdk` module.

**Installation:**
```bash
npm install nostr-sdk
```

**Key Concepts:**
- **nsec**: Private key in bech32 format (starts with `nsec1`)
- **npub**: Public key in bech32 format (starts with `npub1`)
- **Relays**: WebSocket servers that propagate Nostr events
- **Events**: Signed JSON objects representing posts, DMs, etc.
- **POW**: Proof of Work (mining) to reduce spam

**Default Relays:**
- wss://relay.damus.io
- wss://nos.lol
- wss://relay.snort.social
- wss://nostr-pub.wellorder.net
- wss://nostr.oxtr.dev
- And 9+ more for maximum reach

---

## Skills

### post_public_note

Post a public text note to Nostr.

**Usage:**
```javascript
const { posttoNostr } = require("nostr-sdk");

const result = await posttoNostr("Hello Nostr! #introduction", {
  nsec: "nsec1...your-private-key",
  tags: [],
  relays: null,
  powDifficulty: 4
});
console.log(result);
```

**Parameters:**
- `message`: Text content to post
- `tags`: Optional array of tags (e.g., `[['t', 'topic']]`)
- `relays`: Optional custom relay list (uses defaults if null)
- `powDifficulty`: Proof of work difficulty (default: 4, 0 to disable)

**Auto-extracted Tags:**
- Hashtags: `#nostr` → `["t", "nostr"]`
- Mentions: `@npub1...` → `["p", <pubkey>]`
- Links: URLs automatically preserved
- Notes: `note1...` references → `["e", <event-id>]`

**Response:**
```javascript
{
  success: true,
  eventId: "abc123...",
  published: 12,      // Successfully published to 12 relays
  failed: 2,          // Failed on 2 relays
  totalRelays: 14,
  powDifficulty: 4,
  errors: []
}
```

**When to use:**
- User wants to post a public message
- Sharing content with hashtags
- Broadcasting announcements

---

### reply_to_post

Reply to an existing Nostr post.

**Usage:**
```javascript
const { replyToPost } = require("nostr-sdk");

const result = await replyToPost(
  "note1...event-id",           // Event ID (note or hex format)
  "Great post! @npub1...author", // Reply message
  "npub1...author-pubkey",      // Author's public key
  [],                           // Additional tags
  null,                         // Use default relays
  4                             // POW difficulty
);
```

**When to use:**
- Responding to a specific post
- Thread conversations
- Engaging with content

---

### send_encrypted_dm (NIP-4)

Send encrypted direct message using legacy NIP-4 standard.

**Usage:**
```javascript
const { sendmessage } = require("nostr-sdk");

const result = await sendmessage(
  "npub1...recipient",    // Recipient's public key
  "Secret message here",  // Message content
  { nsec: "nsec1...your-private-key" }
);
```

**When to use:**
- Compatibility with older Nostr clients
- Basic encrypted messaging
- Wide client support

**Limitations:**
- Sender/recipient metadata visible
- Older encryption (NIP-04)

---

### send_encrypted_dm_modern (NIP-17)

Send gift-wrapped encrypted message using NIP-17 (recommended).

**Usage:**
```javascript
const { sendMessageNIP17 } = require("nostr-sdk");

const result = await sendMessageNIP17(
  "npub1...recipient",    // Recipient's public key
  "Private message!",     // Message content
  { nsec: "nsec1...your-private-key" }
);
```

**Benefits:**
- Sealed sender (hides who sent the message)
- Better metadata protection
- Modern NIP-44 encryption
- Ephemeral keys for each message

**When to use:**
- Maximum privacy needed
- Modern applications
- Hiding sender identity

---

### receive_messages (NIP-4)

Listen for incoming direct messages.

**Usage:**
```javascript
const { getmessage } = require("nostr-sdk");

const unsubscribe = getmessage((message) => {
  console.log("From:", message.senderNpub);
  console.log("Message:", message.content);
  console.log("Time:", new Date(message.timestamp * 1000));
}, {
  nsec: "nsec1...your-private-key",
  since: Math.floor(Date.now() / 1000) - 3600  // Last hour
});

// Stop listening:
// unsubscribe();
```

**Message Object:**
```javascript
{
  id: "event-id",
  sender: "hex-pubkey",
  senderNpub: "npub1...",
  content: "decrypted message",
  timestamp: 1234567890,
  event: { /* full event */ }
}
```

**When to use:**
- Building a chat bot
- Receiving DMs
- Monitoring for messages

---

### receive_messages_modern (NIP-17)

Listen for incoming NIP-17 gift-wrapped messages.

**Usage:**
```javascript
const { getMessageNIP17 } = require("nostr-sdk");

const unsubscribe = getMessageNIP17((message) => {
  console.log("From:", message.senderNpub);
  console.log("Content:", message.content);
  console.log("Wrapped ID:", message.wrappedEventId);
}, {
  nsec: "nsec1...your-private-key",
  since: Math.floor(Date.now() / 1000) - 300  // Last 5 minutes
});

// Stop listening:
// unsubscribe();
```

**When to use:**
- Receiving modern private messages
- Maximum privacy for incoming DMs
- Supporting NIP-17 protocol

---

### get_global_feed

Fetch recent posts from the global Nostr feed.

**Usage:**
```javascript
const { getGlobalFeed } = require("nostr-sdk");

const events = await getGlobalFeed({
  limit: 50,                                    // Max 50 posts
  since: Math.floor(Date.now() / 1000) - 3600, // Last hour
  until: null,                                  // Up to now
  kinds: [1],                                   // Text notes only
  authors: null,                                // All authors
  relays: null                                  // Use defaults
});

events.forEach(event => {
  console.log("Author:", event.authorNpub);
  console.log("Content:", event.content);
  console.log("Note ID:", event.noteId);
  console.log("Posted:", event.createdAtDate);
});
```

**When to use:**
- Building a feed reader
- Monitoring public posts
- Trending content analysis

---

### generate_keys

Generate new Nostr key pair.

**Usa