mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-06-04 09:41:13 +02:00
chore: sync NIPs
This commit is contained in:
@@ -21,7 +21,7 @@ Read the current file, then:
|
||||
### VALID_NIPS array
|
||||
- Add new NIP identifiers found upstream
|
||||
- Remove NIPs no longer listed upstream (unless referenced by a kind in `kinds.ts`)
|
||||
- Maintain sort order: numeric first (`"01"`–`"99"`), then hexadecimal (`"7D"`, `"A0"`, etc.)
|
||||
- Maintain sort order: numeric first (`"01"`–`"99"`), then hexadecimal (`"5A"`, `"7D"`, `"A0"`, etc.)
|
||||
- Preserve the `// Numeric NIPs` and `// Hexadecimal NIPs` section comments
|
||||
|
||||
### NIP_TITLES record
|
||||
@@ -30,10 +30,27 @@ Read the current file, then:
|
||||
- Keep existing entries that still match
|
||||
|
||||
### DEPRECATED_NIPS array
|
||||
- Sync with upstream: add NIPs marked `deprecated`, remove ones no longer deprecated
|
||||
- Sync with upstream: add NIPs marked `unrecommended`/`deprecated`, remove ones no longer deprecated
|
||||
- Keep `as const` assertion
|
||||
|
||||
## Step 3: Update `src/constants/kinds.ts`
|
||||
## Step 3: Update `src/lib/nip-icons.ts`
|
||||
|
||||
Read the current file. The `NIP_METADATA` record provides icons, short names, and descriptions for each NIP — used by NIPBadge and NipsViewer.
|
||||
|
||||
### For every new NIP added in Step 2:
|
||||
- Add a corresponding entry to `NIP_METADATA` with: `id` (string, matches the NIP identifier), `name` (short), `description`, `icon` (lucide-react), and `deprecated` if applicable
|
||||
- All keys and `id` values are strings (e.g., `"01"`, `"5A"`, `"A0"`)
|
||||
- Pick an icon from existing imports; add new imports if needed
|
||||
- Place in correct position (numeric keys first, then hex keys sorted)
|
||||
|
||||
### For deprecated status changes:
|
||||
- Add or remove the `deprecated: true` field to match upstream
|
||||
|
||||
### Preserve existing entries:
|
||||
- Never change icons on existing entries
|
||||
- Only update name/description if upstream changed
|
||||
|
||||
## Step 4: Update `src/constants/kinds.ts`
|
||||
|
||||
Read the current file, then apply changes carefully.
|
||||
|
||||
@@ -57,13 +74,14 @@ Read the current file, then apply changes carefully.
|
||||
- If the NIP reference changed, update the `nip` field
|
||||
- **Never** change the `icon` field on existing entries
|
||||
|
||||
## Step 4: Cross-reference validation
|
||||
## Step 5: Cross-reference validation
|
||||
|
||||
- Every `nip` field in `EVENT_KINDS` should exist in `VALID_NIPS` (except empty strings `""` and external specs like `"BUD-03"`, `"AMB"`, `"85"`)
|
||||
- Every `nip` field in `EVENT_KINDS` should exist in `VALID_NIPS` (except empty strings `""` and external specs like `"BUD-03"`, `"AMB"`, `"Marmot"`)
|
||||
- Every NIP in `DEPRECATED_NIPS` should also be in `VALID_NIPS`
|
||||
- Every NIP in `VALID_NIPS` should have a corresponding entry in `NIP_METADATA` (`src/lib/nip-icons.ts`)
|
||||
- Flag and fix any inconsistencies
|
||||
|
||||
## Step 5: Verify
|
||||
## Step 6: Verify
|
||||
|
||||
```bash
|
||||
npm run lint && npm run test:run && npm run build
|
||||
@@ -71,10 +89,11 @@ npm run lint && npm run test:run && npm run build
|
||||
|
||||
Fix any lint/type/build issues before reporting.
|
||||
|
||||
## Step 6: Report
|
||||
## Step 7: Report
|
||||
|
||||
Summarize:
|
||||
- NIPs added / removed / title-updated
|
||||
- NIP icons added / updated in `nip-icons.ts`
|
||||
- Kinds added / updated (with icon choices explained for new ones)
|
||||
- Inconsistencies found and resolved
|
||||
- Verification results (lint/test/build)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getNIPInfo } from "../lib/nip-icons";
|
||||
import { useAddWindow } from "@/core/state";
|
||||
import { isNipDeprecated } from "@/constants/nips";
|
||||
import { isNipDeprecated, isValidNip } from "@/constants/nips";
|
||||
import { getCommunityNipForNipId } from "@/constants/kinds";
|
||||
|
||||
export interface NIPBadgeProps {
|
||||
@@ -26,6 +26,7 @@ export function NIPBadge({
|
||||
const description =
|
||||
nipInfo?.description || `Nostr Implementation Possibility ${nipNumber}`;
|
||||
const isDeprecated = isNipDeprecated(nipNumber);
|
||||
const isExternal = !isValidNip(nipNumber);
|
||||
|
||||
const communityNip = getCommunityNipForNipId(nipNumber);
|
||||
|
||||
@@ -48,6 +49,18 @@ export function NIPBadge({
|
||||
);
|
||||
};
|
||||
|
||||
// External specs (Marmot, BUD-03, etc.) render as non-interactive labels
|
||||
if (isExternal && !communityNip) {
|
||||
return (
|
||||
<span
|
||||
className={`flex items-center gap-2 border bg-card px-2.5 py-1.5 text-sm ${className}`}
|
||||
title={`${nipNumber} (External spec)`}
|
||||
>
|
||||
<span className="text-muted-foreground">{nipNumber}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={openNIP}
|
||||
|
||||
@@ -95,7 +95,7 @@ const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [
|
||||
name: "KeyPackage Relays",
|
||||
description:
|
||||
"Relays where you publish MLS KeyPackage events. Anyone who wants to start an encrypted group chat with you looks up this list.",
|
||||
nip: "EE",
|
||||
nip: "Marmot",
|
||||
tagName: "relay",
|
||||
hasMarkers: false,
|
||||
},
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
Gavel,
|
||||
GitBranch,
|
||||
GitMerge,
|
||||
Globe,
|
||||
GitPullRequest,
|
||||
GraduationCap,
|
||||
BookHeart,
|
||||
@@ -251,6 +252,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "71",
|
||||
icon: Video,
|
||||
},
|
||||
24: {
|
||||
kind: 24,
|
||||
name: "Public Message",
|
||||
description: "Public Message",
|
||||
nip: "A4",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
|
||||
// References (NKBIP-03) - External spec, commented out
|
||||
// 30: {
|
||||
@@ -789,6 +797,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "51",
|
||||
icon: Users,
|
||||
},
|
||||
10011: {
|
||||
kind: 10011,
|
||||
name: "External Identities",
|
||||
description: "External Identities",
|
||||
nip: "39",
|
||||
icon: UserCheck,
|
||||
},
|
||||
10012: {
|
||||
kind: 10012,
|
||||
name: "Favorite Relay List",
|
||||
@@ -842,7 +857,7 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
kind: 10051,
|
||||
name: "KeyPackage Relays",
|
||||
description: "KeyPackage Relays List",
|
||||
nip: "EE",
|
||||
nip: "Marmot",
|
||||
icon: Key,
|
||||
},
|
||||
10040: {
|
||||
@@ -901,13 +916,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "",
|
||||
icon: WandSparkles,
|
||||
},
|
||||
// 10312: {
|
||||
// kind: 10312,
|
||||
// name: "Room Presence",
|
||||
// description: "Room Presence",
|
||||
// nip: "53",
|
||||
// icon: Users,
|
||||
// },
|
||||
10312: {
|
||||
kind: 10312,
|
||||
name: "Room Presence",
|
||||
description: "Room Presence",
|
||||
nip: "53",
|
||||
icon: Users,
|
||||
},
|
||||
// 10377: {
|
||||
// kind: 10377,
|
||||
// name: "Proxy Announce",
|
||||
@@ -934,17 +949,31 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
13534: {
|
||||
kind: 13534,
|
||||
name: "Relay Members",
|
||||
description: "Relay membership list",
|
||||
description: "Membership Lists",
|
||||
nip: "43",
|
||||
icon: Users,
|
||||
},
|
||||
// 17375: {
|
||||
// kind: 17375,
|
||||
// name: "Cashu Wallet Event",
|
||||
// description: "Cashu Wallet Event",
|
||||
// nip: "60",
|
||||
// icon: Wallet,
|
||||
15128: {
|
||||
kind: 15128,
|
||||
name: "Nsite Manifest",
|
||||
description: "Root nsite manifest",
|
||||
nip: "5A",
|
||||
icon: Globe,
|
||||
},
|
||||
// 14388: {
|
||||
// kind: 14388,
|
||||
// name: "Sound Effect List",
|
||||
// description: "User Sound Effect Lists",
|
||||
// nip: "Corny Chat",
|
||||
// icon: Music,
|
||||
// },
|
||||
17375: {
|
||||
kind: 17375,
|
||||
name: "Cashu Wallet Event",
|
||||
description: "Cashu Wallet Event",
|
||||
nip: "60",
|
||||
icon: Wallet,
|
||||
},
|
||||
// 21000: {
|
||||
// kind: 21000,
|
||||
// name: "Lightning Pub RPC",
|
||||
@@ -1124,6 +1153,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "51",
|
||||
icon: Video,
|
||||
},
|
||||
30006: {
|
||||
kind: 30006,
|
||||
name: "Picture Set",
|
||||
description: "Picture sets",
|
||||
nip: "51",
|
||||
icon: Image,
|
||||
},
|
||||
30007: {
|
||||
kind: 30007,
|
||||
name: "Kind Mute Set",
|
||||
@@ -1141,7 +1177,7 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
30009: {
|
||||
kind: 30009,
|
||||
name: "Badge",
|
||||
description: "Badge",
|
||||
description: "Badge Definition",
|
||||
nip: "58",
|
||||
icon: Award,
|
||||
},
|
||||
@@ -1218,7 +1254,7 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
30063: {
|
||||
kind: 30063,
|
||||
name: "App Release",
|
||||
description: "Application release with version and files",
|
||||
description: "Release artifact sets",
|
||||
nip: "51",
|
||||
icon: Package,
|
||||
},
|
||||
@@ -1257,7 +1293,7 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
30267: {
|
||||
kind: 30267,
|
||||
name: "App Collection",
|
||||
description: "Curated collection of applications",
|
||||
description: "App curation sets",
|
||||
nip: "51",
|
||||
icon: BookHeart,
|
||||
},
|
||||
@@ -1271,21 +1307,21 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
30382: {
|
||||
kind: 30382,
|
||||
name: "User Assertion",
|
||||
description: "Trusted Assertion: User",
|
||||
description: "User Trusted Assertion",
|
||||
nip: "85",
|
||||
icon: ShieldCheck,
|
||||
},
|
||||
30383: {
|
||||
kind: 30383,
|
||||
name: "Event Assertion",
|
||||
description: "Trusted Assertion: Event",
|
||||
description: "Event Trusted Assertion",
|
||||
nip: "85",
|
||||
icon: ShieldCheck,
|
||||
},
|
||||
30384: {
|
||||
kind: 30384,
|
||||
name: "Address Assertion",
|
||||
description: "Trusted Assertion: Addressable Event",
|
||||
description: "Addressable Trusted Assertion",
|
||||
nip: "85",
|
||||
icon: ShieldCheck,
|
||||
},
|
||||
@@ -1425,35 +1461,56 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
31989: {
|
||||
kind: 31989,
|
||||
name: "Recommendation",
|
||||
description: "Application Recommendation",
|
||||
description: "Handler recommendation",
|
||||
nip: "89",
|
||||
icon: Star,
|
||||
},
|
||||
31990: {
|
||||
kind: 31990,
|
||||
name: "Application",
|
||||
description: "Application Definition",
|
||||
name: "Handler",
|
||||
description: "Handler information",
|
||||
nip: "89",
|
||||
icon: Package,
|
||||
},
|
||||
32267: {
|
||||
kind: 32267,
|
||||
name: "App",
|
||||
description: "Application metadata with platforms and screenshots",
|
||||
description: "Software Application",
|
||||
nip: "",
|
||||
icon: Package,
|
||||
},
|
||||
// 32388: {
|
||||
// kind: 32388,
|
||||
// name: "Room Favorites",
|
||||
// description: "User Room Favorites",
|
||||
// nip: "Corny Chat",
|
||||
// icon: Star,
|
||||
// },
|
||||
// 33388: {
|
||||
// kind: 33388,
|
||||
// name: "High Scores",
|
||||
// description: "High Scores",
|
||||
// nip: "Corny Chat",
|
||||
// icon: Star,
|
||||
// },
|
||||
34128: {
|
||||
kind: 34128,
|
||||
name: "Legacy Nsite",
|
||||
description: "Legacy nsite manifest (deprecated)",
|
||||
nip: "5A",
|
||||
icon: Globe,
|
||||
},
|
||||
34235: {
|
||||
kind: 34235,
|
||||
name: "Video",
|
||||
description: "Horizontal Video (legacy)",
|
||||
description: "Addressable Video Event",
|
||||
nip: "71",
|
||||
icon: Video,
|
||||
},
|
||||
34236: {
|
||||
kind: 34236,
|
||||
name: "Short Video",
|
||||
description: "Vertical Video (legacy)",
|
||||
description: "Addressable Short Video Event",
|
||||
nip: "71",
|
||||
icon: Video,
|
||||
},
|
||||
@@ -1464,6 +1521,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "",
|
||||
icon: ListMusic,
|
||||
},
|
||||
// 34388: {
|
||||
// kind: 34388,
|
||||
// name: "Sound Effects",
|
||||
// description: "Sound Effects",
|
||||
// nip: "Corny Chat",
|
||||
// icon: Music,
|
||||
// },
|
||||
34550: {
|
||||
kind: 34550,
|
||||
name: "Community",
|
||||
@@ -1471,6 +1535,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "72",
|
||||
icon: Users,
|
||||
},
|
||||
35128: {
|
||||
kind: 35128,
|
||||
name: "Named Nsite",
|
||||
description: "Named nsite manifest",
|
||||
nip: "5A",
|
||||
icon: Globe,
|
||||
},
|
||||
36787: {
|
||||
kind: 36787,
|
||||
name: "Music Track",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Deprecated NIPs that are no longer recommended for use
|
||||
*/
|
||||
export const DEPRECATED_NIPS = ["04", "08", "26", "96"] as const;
|
||||
export const DEPRECATED_NIPS = ["04", "08", "26", "96", "EE"] as const;
|
||||
|
||||
export const VALID_NIPS = [
|
||||
// Numeric NIPs
|
||||
@@ -79,6 +79,7 @@ export const VALID_NIPS = [
|
||||
"77",
|
||||
"78",
|
||||
"84",
|
||||
"85",
|
||||
"86",
|
||||
"87",
|
||||
"88",
|
||||
@@ -90,8 +91,10 @@ export const VALID_NIPS = [
|
||||
"98",
|
||||
"99",
|
||||
// Hexadecimal NIPs
|
||||
"5A",
|
||||
"7D",
|
||||
"A0",
|
||||
"A4",
|
||||
"B0",
|
||||
"B7",
|
||||
"BE",
|
||||
@@ -177,6 +180,7 @@ export const NIP_TITLES: Record<string, string> = {
|
||||
"78": "Application-specific data",
|
||||
"7D": "Threads",
|
||||
"84": "Highlights",
|
||||
"85": "Trusted Assertions",
|
||||
"86": "Relay Management API",
|
||||
"87": "Ecash Mint Discoverability",
|
||||
"88": "Polls",
|
||||
@@ -187,7 +191,9 @@ export const NIP_TITLES: Record<string, string> = {
|
||||
"96": "HTTP File Storage Integration",
|
||||
"98": "HTTP Auth",
|
||||
"99": "Classified Listings",
|
||||
"5A": "Pubkey Static Websites",
|
||||
A0: "Voice Messages",
|
||||
A4: "Public Messages",
|
||||
B0: "Web Bookmarks",
|
||||
B7: "Blossom",
|
||||
BE: "Nostr BLE Communications Protocol",
|
||||
@@ -207,6 +213,10 @@ export function getNipTitle(nipId: string): string {
|
||||
return NIP_TITLES[nipId] || `NIP-${nipId}`;
|
||||
}
|
||||
|
||||
export function isValidNip(nipId: string): boolean {
|
||||
return VALID_NIPS.includes(nipId as NipId);
|
||||
}
|
||||
|
||||
export function isNipDeprecated(nipId: string): boolean {
|
||||
return DEPRECATED_NIPS.includes(nipId as any);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* NIP Icon Mapping
|
||||
* Maps NIP numbers to Lucide icons for visual representation
|
||||
* Maps NIP identifiers to Lucide icons for visual representation
|
||||
*/
|
||||
|
||||
import {
|
||||
@@ -46,539 +46,506 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
export interface NIPInfo {
|
||||
number: number;
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: LucideIcon;
|
||||
deprecated?: boolean;
|
||||
}
|
||||
|
||||
export const NIP_METADATA: Record<number | string, NIPInfo> = {
|
||||
export const NIP_METADATA: Record<string, NIPInfo> = {
|
||||
// Core Protocol
|
||||
"01": {
|
||||
number: 1,
|
||||
id: "01",
|
||||
name: "Basic Protocol",
|
||||
description: "Basic protocol flow description",
|
||||
icon: FileText,
|
||||
},
|
||||
"02": {
|
||||
number: 2,
|
||||
id: "02",
|
||||
name: "Follow List",
|
||||
description: "Contact list and petnames",
|
||||
icon: Users,
|
||||
},
|
||||
"03": {
|
||||
number: 3,
|
||||
id: "03",
|
||||
name: "OpenTimestamps Attestations for Events",
|
||||
description: "A proof of any event",
|
||||
icon: Signature,
|
||||
},
|
||||
"04": {
|
||||
number: 4,
|
||||
id: "04",
|
||||
name: "Encrypted DMs",
|
||||
description: "Encrypted direct messages",
|
||||
icon: Mail,
|
||||
deprecated: true,
|
||||
},
|
||||
"05": {
|
||||
number: 5,
|
||||
id: "05",
|
||||
name: "Mapping Nostr keys to DNS",
|
||||
description: "Mapping Nostr keys to DNS-based internet identifiers",
|
||||
icon: Globe,
|
||||
},
|
||||
"06": {
|
||||
number: 6,
|
||||
id: "06",
|
||||
name: "Key Derivation",
|
||||
description: "Basic key derivation from mnemonic seed phrase",
|
||||
icon: Key,
|
||||
},
|
||||
"07": {
|
||||
number: 7,
|
||||
id: "07",
|
||||
name: "window.nostr",
|
||||
description: "window.nostr capability for web browsers",
|
||||
icon: Globe,
|
||||
},
|
||||
"08": {
|
||||
number: 8,
|
||||
id: "08",
|
||||
name: "Mentions",
|
||||
description: "Handling mentions",
|
||||
icon: Tag,
|
||||
deprecated: true,
|
||||
},
|
||||
"09": {
|
||||
number: 9,
|
||||
id: "09",
|
||||
name: "Event Deletion",
|
||||
description: "Event deletion",
|
||||
icon: AlertCircle,
|
||||
},
|
||||
10: {
|
||||
number: 10,
|
||||
"10": {
|
||||
id: "10",
|
||||
name: "Conventions",
|
||||
description: "Conventions for clients' use of e and p tags",
|
||||
icon: Tag,
|
||||
},
|
||||
11: {
|
||||
number: 11,
|
||||
"11": {
|
||||
id: "11",
|
||||
name: "Relay Info",
|
||||
description: "Relay information document",
|
||||
icon: Server,
|
||||
},
|
||||
13: {
|
||||
number: 13,
|
||||
"13": {
|
||||
id: "13",
|
||||
name: "Proof of Work",
|
||||
description: "Proof of work",
|
||||
icon: Zap,
|
||||
},
|
||||
14: {
|
||||
number: 14,
|
||||
"14": {
|
||||
id: "14",
|
||||
name: "Subject Tag",
|
||||
description: "Subject tag in text events",
|
||||
icon: Tag,
|
||||
},
|
||||
15: {
|
||||
number: 15,
|
||||
"15": {
|
||||
id: "15",
|
||||
name: "Marketplace",
|
||||
description: "Marketplace (for resilient marketplaces)",
|
||||
icon: ShoppingCart,
|
||||
},
|
||||
17: {
|
||||
number: 17,
|
||||
"17": {
|
||||
id: "17",
|
||||
name: "Private DMs",
|
||||
description: "Private Direct Messages",
|
||||
icon: Lock,
|
||||
},
|
||||
18: { number: 18, name: "Reposts", description: "Reposts", icon: Share2 },
|
||||
19: {
|
||||
number: 19,
|
||||
"18": { id: "18", name: "Reposts", description: "Reposts", icon: Share2 },
|
||||
"19": {
|
||||
id: "19",
|
||||
name: "bech32 Entities",
|
||||
description: "bech32-encoded entities",
|
||||
icon: Hash,
|
||||
},
|
||||
21: {
|
||||
number: 21,
|
||||
"21": {
|
||||
id: "21",
|
||||
name: "nostr: URI",
|
||||
description: "nostr: URI scheme",
|
||||
icon: Link,
|
||||
},
|
||||
22: {
|
||||
number: 22,
|
||||
"22": {
|
||||
id: "22",
|
||||
name: "Comment",
|
||||
description: "Comment",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
23: {
|
||||
number: 23,
|
||||
"23": {
|
||||
id: "23",
|
||||
name: "Long-form",
|
||||
description: "Long-form content",
|
||||
icon: FileText,
|
||||
},
|
||||
24: {
|
||||
number: 24,
|
||||
"24": {
|
||||
id: "24",
|
||||
name: "Extra Metadata",
|
||||
description: "Extra metadata fields and tags",
|
||||
icon: Tag,
|
||||
},
|
||||
25: { number: 25, name: "Reactions", description: "Reactions", icon: Heart },
|
||||
26: {
|
||||
number: 26,
|
||||
"25": { id: "25", name: "Reactions", description: "Reactions", icon: Heart },
|
||||
"26": {
|
||||
id: "26",
|
||||
name: "Delegated Signing",
|
||||
description: "Delegated event signing",
|
||||
icon: Key,
|
||||
deprecated: true,
|
||||
},
|
||||
27: {
|
||||
number: 27,
|
||||
"27": {
|
||||
id: "27",
|
||||
name: "Text Note References",
|
||||
description: "Text note references",
|
||||
icon: Link,
|
||||
},
|
||||
28: {
|
||||
number: 28,
|
||||
"28": {
|
||||
id: "28",
|
||||
name: "Public Chat",
|
||||
description: "Public chat",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
29: {
|
||||
number: 29,
|
||||
"29": {
|
||||
id: "29",
|
||||
name: "Relay Groups",
|
||||
description: "Relay-based groups",
|
||||
icon: Users,
|
||||
},
|
||||
30: {
|
||||
number: 30,
|
||||
"30": {
|
||||
id: "30",
|
||||
name: "Custom Emoji",
|
||||
description: "Custom emoji",
|
||||
icon: Gift,
|
||||
},
|
||||
31: {
|
||||
number: 31,
|
||||
"31": {
|
||||
id: "31",
|
||||
name: "Unknown Events",
|
||||
description: "Dealing with unknown event kinds",
|
||||
icon: AlertCircle,
|
||||
},
|
||||
32: { number: 32, name: "Labeling", description: "Labeling", icon: Tag },
|
||||
34: { number: 34, name: "Git", description: "git stuff", icon: GitBranch },
|
||||
35: { number: 35, name: "Torrents", description: "Torrents", icon: Share2 },
|
||||
36: {
|
||||
number: 36,
|
||||
"32": { id: "32", name: "Labeling", description: "Labeling", icon: Tag },
|
||||
"34": { id: "34", name: "Git", description: "git stuff", icon: GitBranch },
|
||||
"35": { id: "35", name: "Torrents", description: "Torrents", icon: Share2 },
|
||||
"36": {
|
||||
id: "36",
|
||||
name: "Sensitive Content",
|
||||
description: "Sensitive content warnings",
|
||||
icon: Eye,
|
||||
},
|
||||
37: {
|
||||
number: 37,
|
||||
"37": {
|
||||
id: "37",
|
||||
name: "Draft Events",
|
||||
description: "Draft Events",
|
||||
icon: FileText,
|
||||
},
|
||||
38: {
|
||||
number: 38,
|
||||
"38": {
|
||||
id: "38",
|
||||
name: "User Status",
|
||||
description: "User statuses",
|
||||
icon: Flag,
|
||||
},
|
||||
39: {
|
||||
number: 39,
|
||||
"39": {
|
||||
id: "39",
|
||||
name: "External Identity",
|
||||
description: "External identities in profiles",
|
||||
icon: Globe,
|
||||
},
|
||||
40: {
|
||||
number: 40,
|
||||
"40": {
|
||||
id: "40",
|
||||
name: "Expiration",
|
||||
description: "Expiration timestamp",
|
||||
icon: Calendar,
|
||||
},
|
||||
42: {
|
||||
number: 42,
|
||||
"42": {
|
||||
id: "42",
|
||||
name: "Authentication",
|
||||
description: "Authentication of clients to relays",
|
||||
icon: Shield,
|
||||
},
|
||||
43: {
|
||||
number: 43,
|
||||
"43": {
|
||||
id: "43",
|
||||
name: "Relay Access",
|
||||
description: "Fast Authentication and Relay Access",
|
||||
icon: Server,
|
||||
},
|
||||
44: {
|
||||
number: 44,
|
||||
"44": {
|
||||
id: "44",
|
||||
name: "Encrypted Payloads",
|
||||
description: "Encrypted Payloads (Versioned)",
|
||||
icon: Lock,
|
||||
},
|
||||
45: {
|
||||
number: 45,
|
||||
"45": {
|
||||
id: "45",
|
||||
name: "Event Counts",
|
||||
description: "Counting results",
|
||||
icon: Hash,
|
||||
},
|
||||
46: {
|
||||
number: 46,
|
||||
"46": {
|
||||
id: "46",
|
||||
name: "Remote Signing",
|
||||
description: "Nostr connect protocol",
|
||||
icon: Key,
|
||||
},
|
||||
47: {
|
||||
number: 47,
|
||||
"47": {
|
||||
id: "47",
|
||||
name: "Wallet Connect",
|
||||
description: "Wallet connect",
|
||||
icon: Wallet,
|
||||
},
|
||||
48: { number: 48, name: "Proxy Tags", description: "Proxy tags", icon: Tag },
|
||||
49: {
|
||||
number: 49,
|
||||
"48": { id: "48", name: "Proxy Tags", description: "Proxy tags", icon: Tag },
|
||||
"49": {
|
||||
id: "49",
|
||||
name: "Private Key Encryption",
|
||||
description: "Private key encryption",
|
||||
icon: Lock,
|
||||
},
|
||||
50: {
|
||||
number: 50,
|
||||
"50": {
|
||||
id: "50",
|
||||
name: "Search",
|
||||
description: "Search capability",
|
||||
icon: Search,
|
||||
},
|
||||
51: { number: 51, name: "Lists", description: "Lists", icon: Filter },
|
||||
52: {
|
||||
number: 52,
|
||||
"51": { id: "51", name: "Lists", description: "Lists", icon: Filter },
|
||||
"52": {
|
||||
id: "52",
|
||||
name: "Calendar Events",
|
||||
description: "Calendar Events",
|
||||
icon: Calendar,
|
||||
},
|
||||
53: {
|
||||
number: 53,
|
||||
"53": {
|
||||
id: "53",
|
||||
name: "Live Activities",
|
||||
description: "Live Activities",
|
||||
icon: Radio,
|
||||
},
|
||||
54: { number: 54, name: "Wiki", description: "Wiki", icon: FileText },
|
||||
55: {
|
||||
number: 55,
|
||||
"54": { id: "54", name: "Wiki", description: "Wiki", icon: FileText },
|
||||
"55": {
|
||||
id: "55",
|
||||
name: "Android Signer",
|
||||
description: "Android Signer Application",
|
||||
icon: Key,
|
||||
},
|
||||
56: { number: 56, name: "Reporting", description: "Reporting", icon: Flag },
|
||||
57: {
|
||||
number: 57,
|
||||
"56": { id: "56", name: "Reporting", description: "Reporting", icon: Flag },
|
||||
"57": {
|
||||
id: "57",
|
||||
name: "Lightning Zaps",
|
||||
description: "Lightning zaps",
|
||||
icon: Zap,
|
||||
},
|
||||
58: { number: 58, name: "Badges", description: "Badges", icon: Star },
|
||||
59: { number: 59, name: "Gift Wrap", description: "Gift Wrap", icon: Gift },
|
||||
60: {
|
||||
number: 60,
|
||||
"58": { id: "58", name: "Badges", description: "Badges", icon: Star },
|
||||
"59": { id: "59", name: "Gift Wrap", description: "Gift Wrap", icon: Gift },
|
||||
"60": {
|
||||
id: "60",
|
||||
name: "Cashu Wallet",
|
||||
description: "Cashu Wallet",
|
||||
icon: Wallet,
|
||||
},
|
||||
61: { number: 61, name: "Nutzaps", description: "Nutzaps", icon: Zap },
|
||||
62: {
|
||||
number: 62,
|
||||
"61": { id: "61", name: "Nutzaps", description: "Nutzaps", icon: Zap },
|
||||
"62": {
|
||||
id: "62",
|
||||
name: "Request to Vanish",
|
||||
description: "Request to Vanish",
|
||||
icon: Eye,
|
||||
},
|
||||
64: { number: 64, name: "Chess", description: "Chess (PGN)", icon: Gamepad2 },
|
||||
65: {
|
||||
number: 65,
|
||||
"64": { id: "64", name: "Chess", description: "Chess (PGN)", icon: Gamepad2 },
|
||||
"65": {
|
||||
id: "65",
|
||||
name: "Relay List",
|
||||
description: "Relay list metadata",
|
||||
icon: Server,
|
||||
},
|
||||
66: {
|
||||
number: 66,
|
||||
"66": {
|
||||
id: "66",
|
||||
name: "Relay Discovery",
|
||||
description: "Relay Discovery",
|
||||
icon: Compass,
|
||||
},
|
||||
68: {
|
||||
number: 68,
|
||||
"68": {
|
||||
id: "68",
|
||||
name: "Picture-first",
|
||||
description: "Picture-first feeds",
|
||||
icon: Image,
|
||||
},
|
||||
69: {
|
||||
number: 69,
|
||||
"69": {
|
||||
id: "69",
|
||||
name: "P2P Order",
|
||||
description: "Peer-to-peer Order events",
|
||||
icon: ShoppingCart,
|
||||
},
|
||||
70: {
|
||||
number: 70,
|
||||
"70": {
|
||||
id: "70",
|
||||
name: "Protected Events",
|
||||
description: "Protected Events",
|
||||
icon: Shield,
|
||||
},
|
||||
71: {
|
||||
number: 71,
|
||||
"71": {
|
||||
id: "71",
|
||||
name: "Video Events",
|
||||
description: "Video Events",
|
||||
icon: Video,
|
||||
},
|
||||
72: {
|
||||
number: 72,
|
||||
"72": {
|
||||
id: "72",
|
||||
name: "Moderation",
|
||||
description: "Moderated communities",
|
||||
icon: Shield,
|
||||
},
|
||||
73: {
|
||||
number: 73,
|
||||
"73": {
|
||||
id: "73",
|
||||
name: "External Content IDs",
|
||||
description: "External Content IDs",
|
||||
icon: Link,
|
||||
},
|
||||
75: { number: 75, name: "Zap Goals", description: "Zap Goals", icon: Zap },
|
||||
77: {
|
||||
number: 77,
|
||||
"75": { id: "75", name: "Zap Goals", description: "Zap Goals", icon: Zap },
|
||||
"77": {
|
||||
id: "77",
|
||||
name: "Negentropy",
|
||||
description: "Negentropy Protocol Sync",
|
||||
icon: Server,
|
||||
},
|
||||
78: {
|
||||
number: 78,
|
||||
"78": {
|
||||
id: "78",
|
||||
name: "App Data",
|
||||
description: "Application-specific data",
|
||||
icon: Database,
|
||||
},
|
||||
84: {
|
||||
number: 84,
|
||||
"84": {
|
||||
id: "84",
|
||||
name: "Highlights",
|
||||
description: "Highlights",
|
||||
icon: Bookmark,
|
||||
},
|
||||
86: {
|
||||
number: 86,
|
||||
"85": {
|
||||
id: "85",
|
||||
name: "Trusted Assertions",
|
||||
description: "Trusted Assertions",
|
||||
icon: Shield,
|
||||
},
|
||||
"86": {
|
||||
id: "86",
|
||||
name: "Relay Management",
|
||||
description: "Relay Management API",
|
||||
icon: Server,
|
||||
},
|
||||
87: {
|
||||
number: 87,
|
||||
"87": {
|
||||
id: "87",
|
||||
name: "Ecash Mints",
|
||||
description: "Ecash Mint Discoverability",
|
||||
icon: Coins,
|
||||
},
|
||||
88: { number: 88, name: "Polls", description: "Polls", icon: Filter },
|
||||
89: {
|
||||
number: 89,
|
||||
"88": { id: "88", name: "Polls", description: "Polls", icon: Filter },
|
||||
"89": {
|
||||
id: "89",
|
||||
name: "App Handlers",
|
||||
description: "Recommended application handlers",
|
||||
icon: Package,
|
||||
},
|
||||
90: {
|
||||
number: 90,
|
||||
"90": {
|
||||
id: "90",
|
||||
name: "Data Vending",
|
||||
description: "Data Vending Machines",
|
||||
icon: Database,
|
||||
},
|
||||
92: {
|
||||
number: 92,
|
||||
"92": {
|
||||
id: "92",
|
||||
name: "Media Attachments",
|
||||
description: "Media Attachments",
|
||||
icon: Image,
|
||||
},
|
||||
94: {
|
||||
number: 94,
|
||||
"94": {
|
||||
id: "94",
|
||||
name: "File Metadata",
|
||||
description: "File metadata",
|
||||
icon: Image,
|
||||
},
|
||||
96: {
|
||||
number: 96,
|
||||
"96": {
|
||||
id: "96",
|
||||
name: "HTTP File Storage",
|
||||
description: "HTTP File Storage Integration",
|
||||
icon: Server,
|
||||
deprecated: true,
|
||||
},
|
||||
98: {
|
||||
number: 98,
|
||||
"98": {
|
||||
id: "98",
|
||||
name: "HTTP Auth",
|
||||
description: "HTTP authentication",
|
||||
icon: Lock,
|
||||
},
|
||||
99: {
|
||||
number: 99,
|
||||
"99": {
|
||||
id: "99",
|
||||
name: "Classified Listings",
|
||||
description: "Classified listings",
|
||||
icon: Tag,
|
||||
},
|
||||
|
||||
// Hex NIPs (A0-EE)
|
||||
// Hex NIPs (5A-EE)
|
||||
"5A": {
|
||||
id: "5A",
|
||||
name: "Static Websites",
|
||||
description: "Pubkey Static Websites",
|
||||
icon: Globe,
|
||||
},
|
||||
"7D": {
|
||||
id: "7D",
|
||||
name: "Threads",
|
||||
description: "Threads",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
A0: {
|
||||
number: 0xa0,
|
||||
id: "A0",
|
||||
name: "Voice Messages",
|
||||
description: "Voice Messages",
|
||||
icon: Music,
|
||||
},
|
||||
A4: {
|
||||
id: "A4",
|
||||
name: "Public Messages",
|
||||
description: "Public Messages",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
B0: {
|
||||
number: 0xb0,
|
||||
id: "B0",
|
||||
name: "Web Bookmarks",
|
||||
description: "Web Bookmarks",
|
||||
icon: Bookmark,
|
||||
},
|
||||
B7: { number: 0xb7, name: "Blossom", description: "Blossom", icon: Package },
|
||||
B7: { id: "B7", name: "Blossom", description: "Blossom", icon: Package },
|
||||
BE: {
|
||||
number: 0xbe,
|
||||
id: "BE",
|
||||
name: "BLE",
|
||||
description: "BLE Communications",
|
||||
icon: Radio,
|
||||
},
|
||||
C0: {
|
||||
number: 0xc0,
|
||||
id: "C0",
|
||||
name: "Code Snippets",
|
||||
description: "Code Snippets",
|
||||
icon: Code,
|
||||
},
|
||||
C7: {
|
||||
number: 0xc7,
|
||||
id: "C7",
|
||||
name: "Chats",
|
||||
description: "Chats",
|
||||
icon: MessageSquare,
|
||||
},
|
||||
EE: {
|
||||
number: 0xee,
|
||||
id: "EE",
|
||||
name: "E2EE MLS",
|
||||
description: "E2EE Messaging (MLS)",
|
||||
icon: Lock,
|
||||
},
|
||||
"7D": {
|
||||
number: 0x7d,
|
||||
name: "Threads",
|
||||
description: "Threads",
|
||||
icon: MessageSquare,
|
||||
deprecated: true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get NIP metadata by number (handles both decimal and hex)
|
||||
* Get NIP metadata by identifier (handles both string IDs and numeric lookups)
|
||||
*/
|
||||
export function getNIPInfo(nipNumber: number | string): NIPInfo | undefined {
|
||||
export function getNIPInfo(nipId: number | string): NIPInfo | undefined {
|
||||
const key = typeof nipId === "string" ? nipId : String(nipId);
|
||||
|
||||
// Try direct lookup
|
||||
if (NIP_METADATA[nipNumber]) {
|
||||
return NIP_METADATA[nipNumber];
|
||||
if (NIP_METADATA[key]) {
|
||||
return NIP_METADATA[key];
|
||||
}
|
||||
|
||||
// Try hex conversion for numbers > 99
|
||||
if (typeof nipNumber === "number" && nipNumber > 99) {
|
||||
const hexKey = nipNumber.toString(16).toUpperCase();
|
||||
if (typeof nipId === "number" && nipId > 99) {
|
||||
const hexKey = nipId.toString(16).toUpperCase();
|
||||
return NIP_METADATA[hexKey];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all supported NIPs with their metadata, excluding deprecated ones
|
||||
*/
|
||||
export function getSupportedNIPsInfo(
|
||||
nipNumbers: number[],
|
||||
includeDeprecated: boolean = false,
|
||||
): (NIPInfo | { number: number; name: string; icon: LucideIcon })[] {
|
||||
return nipNumbers
|
||||
.map((num) => {
|
||||
const info = getNIPInfo(num);
|
||||
if (info) {
|
||||
// Skip deprecated NIPs unless explicitly included
|
||||
if (!includeDeprecated && info.deprecated) {
|
||||
return null;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
// Fallback for unknown NIPs
|
||||
return {
|
||||
number: num,
|
||||
name: `NIP-${num}`,
|
||||
icon: FileText,
|
||||
};
|
||||
})
|
||||
.filter(
|
||||
(
|
||||
nip,
|
||||
): nip is NIPInfo | { number: number; name: string; icon: LucideIcon } =>
|
||||
nip !== null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Group NIPs by a single consolidated category
|
||||
* For relay viewer, we show all NIPs in one list
|
||||
*/
|
||||
export function groupNIPsByCategory(
|
||||
nipNumbers: number[],
|
||||
): Record<string, NIPInfo[]> {
|
||||
const grouped: Record<string, NIPInfo[]> = {
|
||||
"Supported NIPs": [],
|
||||
};
|
||||
|
||||
nipNumbers.forEach((num) => {
|
||||
const info = getNIPInfo(num);
|
||||
// Skip deprecated NIPs
|
||||
if (info && !info.deprecated) {
|
||||
grouped["Supported NIPs"].push(info);
|
||||
}
|
||||
});
|
||||
|
||||
return grouped;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user