{"id":"a4ac279854824d4e4c97512ded50f837a26687bb9c4cc724ef6a1fd0ca197c88","pubkey":"a8d1560d6a647d501699167246f237b36fb123f89168fda11dc743533fec7a08","created_at":1767488471,"kind":30817,"tags":[["d","shakespearewtf-url-registry"],["title","Shakespeare.wtf URL Registry"],["k","32579"],["client","nostrhub.io"]],"content":"# NIP-XX: Shakespeare.wtf URL Registry\n\n`draft` `optional`\n\nThis NIP defines a standardized way to catalog and share URLs with the format `https://*.shakespeare.wtf` across the Nostr network.\n\n## Kind 32579: Shakespeare URL Entry\n\nA kind `32579` event represents a single shakespeare.wtf URL entry in a distributed registry. This allows clients to efficiently discover and index shakespeare.wtf links without scanning all text notes.\n\n### Event Format\n\n```json\n{\n  \"kind\": 32579,\n  \"tags\": [\n    [\"d\", \"<url-identifier>\"],\n    [\"url\", \"<full-url>\"],\n    [\"title\", \"<optional-title>\"],\n    [\"description\", \"<optional-description>\"],\n    [\"published_at\", \"<unix-timestamp>\"],\n    [\"t\", \"shakespeare\"],\n    [\"category\", \"<root|path>\"]\n  ],\n  \"content\": \"<optional-notes-or-context>\",\n  \"created_at\": <unix-timestamp>,\n  \"pubkey\": \"<author-pubkey>\"\n}\n```\n\n### Tags\n\n- **`d` (required)**: A unique identifier for this URL entry. Recommended format: subdomain name (e.g., `my-app` for `https://my-app.shakespeare.wtf`)\n- **`url` (required)**: The full URL including protocol in the format `https://<subdomain>.shakespeare.wtf` (e.g., `https://my-app.shakespeare.wtf`)\n- **`title` (optional)**: Human-readable title for the URL\n- **`description` (optional)**: Brief description of what the URL points to\n- **`published_at` (optional)**: When the content at this URL was originally published (unix timestamp)\n- **`t` (required)**: Always set to `\"shakespeare\"` for discoverability via relay filtering\n- **`category` (optional)**: Either `\"root\"` for URLs at the subdomain root (e.g., `https://app.shakespeare.wtf`), or `\"path\"` for URLs with additional path segments (e.g., `https://app.shakespeare.wtf/page`)\n\n### Content Field\n\nThe `content` field may contain:\n- Additional notes or context about the URL\n- A quote or excerpt from the linked content\n- Personal commentary from the publisher\n- Empty string if no additional context is needed\n\n### Behavior\n\n- **Replaceable**: Since this is an addressable event (30000-39999 range), only the most recent event per `pubkey` + `kind` + `d` tag combination is kept by relays\n- **User Curation**: Each user can maintain their own list of shakespeare.wtf URLs, with their own titles and descriptions\n- **Deduplication**: Multiple users can catalog the same URL with different `d` tags, titles, or descriptions based on their perspective\n\n## Use Cases\n\n1. **URL Discovery**: Clients can query for all kind 32579 events to find shakespeare.wtf links\n2. **Personal Bookmarks**: Users maintain their own curated list of shakespeare.wtf URLs\n3. **Metadata Enhancement**: Add titles and descriptions to URLs for better presentation\n4. **Category Filtering**: Filter between root URLs and path URLs using the `category` tag\n5. **Efficient Indexing**: Relays can efficiently index and search these events using the `#t` tag filter\n\n## Example Events\n\n### Root URL Entry (subdomain root)\n\n```json\n{\n  \"kind\": 32579,\n  \"tags\": [\n    [\"d\", \"my-app\"],\n    [\"url\", \"https://my-app.shakespeare.wtf\"],\n    [\"title\", \"My Awesome Nostr App\"],\n    [\"description\", \"A social app built with Shakespeare\"],\n    [\"published_at\", \"1704067200\"],\n    [\"t\", \"shakespeare\"],\n    [\"category\", \"root\"]\n  ],\n  \"content\": \"Check out my new Nostr app built with Shakespeare!\",\n  \"created_at\": 1704153600,\n  \"pubkey\": \"a8d1560d6a647d501699167246f237b36fb123f89168fda11dc743533fec7a08\"\n}\n```\n\n### Path URL Entry (subdomain with path)\n\n```json\n{\n  \"kind\": 32579,\n  \"tags\": [\n    [\"d\", \"my-app-article\"],\n    [\"url\", \"https://my-app.shakespeare.wtf/article/getting-started\"],\n    [\"title\", \"Getting Started Guide\"],\n    [\"description\", \"How to use My Awesome Nostr App\"],\n    [\"t\", \"shakespeare\"],\n    [\"category\", \"path\"]\n  ],\n  \"content\": \"A comprehensive guide for new users\",\n  \"created_at\": 1704153600,\n  \"pubkey\": \"b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc\"\n}\n```\n\n## Querying\n\n### Find all Shakespeare URLs\n\n```javascript\nconst urls = await nostr.query([\n  {\n    kinds: [32579],\n    '#t': ['shakespeare'],\n    limit: 100\n  }\n]);\n```\n\n### Find URLs by specific user\n\n```javascript\nconst myUrls = await nostr.query([\n  {\n    kinds: [32579],\n    authors: [userPubkey],\n    '#t': ['shakespeare']\n  }\n]);\n```\n\n### Find only root URLs\n\n```javascript\nconst rootUrls = await nostr.query([\n  {\n    kinds: [32579],\n    '#t': ['shakespeare'],\n    '#category': ['root']\n  }\n]);\n```\n\n## Publishing\n\nWhen publishing a kind 32579 event, always include the NIP-31 `alt` tag for human-readable descriptions:\n\n```json\n{\n  \"kind\": 32579,\n  \"tags\": [\n    [\"d\", \"my-app\"],\n    [\"url\", \"https://my-app.shakespeare.wtf\"],\n    [\"t\", \"shakespeare\"],\n    [\"alt\", \"Shakespeare URL registry entry for https://my-app.shakespeare.wtf\"]\n  ],\n  \"content\": \"\",\n  ...\n}\n```\n\n## Rationale\n\n### Why Not Use Existing Kinds?\n\n- **Kind 30023 (Long-form Content)**: Designed for articles, not URL catalogs\n- **Kind 30001 (Generic Lists)**: Could work but lacks shakespeare-specific semantics\n- **Kind 1 (Text Notes)**: Inefficient for discovery; requires full-text search\n- **Custom Kind**: Provides semantic clarity, efficient querying, and future extensibility\n\n### Why Addressable?\n\nAddressable events allow users to update their entries for specific URLs. For example:\n- Update the title or description\n- Add metadata as it becomes available\n- Correct mistakes without creating duplicates\n\n### URL Format\n\nAll shakespeare.wtf URLs follow the subdomain format:\n- **Format**: `https://<subdomain>.shakespeare.wtf[/path]`\n- **Examples**:\n  - `https://my-app.shakespeare.wtf` (root)\n  - `https://my-app.shakespeare.wtf/page` (with path)\n  - `https://chat.shakespeare.wtf`\n  - `https://blog.shakespeare.wtf/article/123`\n\n### Design Decisions\n\n1. **`d` tag format**: Using the subdomain name (or a descriptive identifier for paths) makes entries human-readable and easy to manage. Each user can organize their registry however they prefer.\n\n2. **`t` tag**: Single-letter tag `t` is indexed by relays, enabling efficient filtering at the relay level without requiring full-text search.\n\n3. **`category` tag**: Allows filtering between subdomain roots and URLs with paths, which have different use cases (main app vs specific pages/articles).\n\n4. **Flexible content**: Supports both minimal entries (just URL + title) and rich entries (with context and commentary).\n\n## Implementation Notes\n\n- All URLs must use HTTPS protocol and follow the subdomain format `https://*.shakespeare.wtf`\n- Clients should validate URL format before creating registry entries\n- The same URL may have multiple entries from different users - this is intentional and allows for crowdsourced curation\n- Clients may choose to deduplicate URLs in their UI or show multiple perspectives\n- For `d` tags, using the subdomain name alone is recommended for root URLs (e.g., `\"my-app\"` for `https://my-app.shakespeare.wtf`)\n\n## References\n\n- [NIP-01: Basic Protocol](https://github.com/nostr-protocol/nips/blob/master/01.md)\n- [NIP-31: alt tag](https://github.com/nostr-protocol/nips/blob/master/31.md)\n- [NIP-33: Parameterized Replaceable Events](https://github.com/nostr-protocol/nips/blob/master/33.md)","sig":"e77bcd4d25c180d0e816841ca636d907c2b1a967009b4b9ad1339eff1cbe38418ec0ea1aa0677c838190851e0c56ef762128aa16f4e63a1bf13bb460764cf4a4"}