@ -3,7 +3,7 @@
@@ -3,7 +3,7 @@
* Based on NIPs from nips - silberengel directory
* /
import { KIND , KIND_LOOKUP , type KindInfo } from './kind-lookup.js' ;
import { KIND , KIND_LOOKUP , getAllKinds , type KindInfo } from './kind-lookup.js' ;
export interface KindMetadata extends KindInfo {
helpText : {
@ -15,24 +15,6 @@ export interface KindMetadata extends KindInfo {
@@ -15,24 +15,6 @@ export interface KindMetadata extends KindInfo {
requiresContent? : boolean ; // Whether content field is required (default: true)
}
// Kinds that can be written via the form
const WRITABLE_KINDS = [
KIND . SHORT_TEXT_NOTE ,
KIND . DISCUSSION_THREAD ,
KIND . PICTURE_NOTE ,
KIND . VIDEO_NOTE ,
KIND . SHORT_VIDEO_NOTE ,
KIND . PUBLIC_MESSAGE ,
KIND . POLL ,
KIND . VOICE_NOTE ,
KIND . HIGHLIGHTED_ARTICLE ,
KIND . RSS_FEED ,
KIND . LONG_FORM_NOTE ,
KIND . PUBLICATION_INDEX ,
KIND . PUBLICATION_CONTENT ,
KIND . WIKI_MARKDOWN ,
KIND . WIKI_ASCIIDOC ,
] as const ;
export const KIND_METADATA : Record < number , KindMetadata > = {
[ KIND . SHORT_TEXT_NOTE ] : {
@ -375,6 +357,694 @@ export const KIND_METADATA: Record<number, KindMetadata> = {
@@ -375,6 +357,694 @@ export const KIND_METADATA: Record<number, KindMetadata> = {
sig : '...'
} )
} ,
[ KIND . METADATA ] : {
. . . KIND_LOOKUP [ KIND . METADATA ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Profile Metadata (NIP-01). Replaceable event that stores user profile information. The content is a JSON string containing profile data.' ,
suggestedTags : [ ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.METADATA ,
pubkey ,
created_at : timestamp ,
content : JSON.stringify ( {
name : 'Alice' ,
about : 'Nostr user' ,
picture : 'https://example.com/avatar.jpg' ,
nip05 : 'alice@example.com'
} ) ,
tags : [ ] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . CONTACTS ] : {
. . . KIND_LOOKUP [ KIND . CONTACTS ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Contact List (NIP-02). Replaceable event that stores a list of contacts (people the user follows). Content should be empty. p tags contain pubkeys of contacts.' ,
suggestedTags : [ 'p (contact pubkeys)' , 'relay (optional relay hints)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.CONTACTS ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'p' , '3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d' , relay ] ,
[ 'p' , '67b48a14fb66c60c8f9070bdeb37afdfcc3d08ad01989460448e4081eddda446' , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . EVENT_DELETION ] : {
. . . KIND_LOOKUP [ KIND . EVENT_DELETION ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Event Deletion (NIP-09). Used to request deletion of events. Content should be empty or contain a deletion reason. e tags reference the events to delete.' ,
suggestedTags : [ 'e (event IDs to delete)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.EVENT_DELETION ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'e' , eventId ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . DELETION_REQUEST ] : {
. . . KIND_LOOKUP [ KIND . DELETION_REQUEST ] ,
writable : true ,
helpText : {
description : 'Deletion Request. Used to request deletion of events from relays. Content may contain a reason.' ,
suggestedTags : [ 'e (event IDs to delete)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.DELETION_REQUEST ,
pubkey ,
created_at : timestamp ,
content : 'Please delete this event' ,
tags : [
[ 'e' , eventId ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . REACTION ] : {
. . . KIND_LOOKUP [ KIND . REACTION ] ,
writable : true ,
helpText : {
description : 'Reaction (NIP-25). Used to react to events. Content is typically a single emoji or +/-, but can be any string. e tag references the event being reacted to.' ,
suggestedTags : [ 'e (event ID being reacted to)' , 'p (author of the event being reacted to)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.REACTION ,
pubkey ,
created_at : timestamp ,
content : '+' ,
tags : [
[ 'e' , eventId , relay ] ,
[ 'p' , pubkey ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . COMMENT ] : {
. . . KIND_LOOKUP [ KIND . COMMENT ] ,
writable : true ,
helpText : {
description : 'Comment (NIP-22). Comments on threads or other events. e tag references the event being commented on. root e tag references the thread root.' ,
suggestedTags : [ 'e (event being commented on)' , 'root (thread root event)' , 'p (author of parent event)' , 't (hashtags)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.COMMENT ,
pubkey ,
created_at : timestamp ,
content : 'This is a comment on a thread.' ,
tags : [
[ 'e' , eventId , relay , 'root' ] ,
[ 'e' , eventId , relay , 'reply' ] ,
[ 'p' , pubkey ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . VOICE_REPLY ] : {
. . . KIND_LOOKUP [ KIND . VOICE_REPLY ] ,
writable : true ,
helpText : {
description : 'Voice Reply (NIP-A0). Reply messages for short voice messages. Content MUST be a URL pointing directly to an audio file. e tag references the event being replied to.' ,
suggestedTags : [ 'e (event being replied to)' , 'p (author of parent event)' , 'imeta (with url, waveform, duration)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.VOICE_REPLY ,
pubkey ,
created_at : timestamp ,
content : 'https://example.com/audio/reply.m4a' ,
tags : [
[ 'e' , eventId , relay ] ,
[ 'p' , pubkey ] ,
[ 'imeta' , 'url https://example.com/audio/reply.m4a' , 'waveform 0 5 20 6 80 90 30' , 'duration 5' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . FILE_METADATA ] : {
. . . KIND_LOOKUP [ KIND . FILE_METADATA ] ,
writable : true ,
helpText : {
description : 'File Metadata (NIP-94). Used to share file metadata, particularly for GIFs. Content should be empty. imeta tag contains file information.' ,
suggestedTags : [ 'imeta (url, m, dim, blurhash, x, alt, fallback)' , 't (hashtags)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.FILE_METADATA ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'imeta' , 'url https://example.com/file.gif' , 'm image/gif' , 'dim 500x500' , 'x abc123' ] ,
[ 't' , 'gif' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . POLL_RESPONSE ] : {
. . . KIND_LOOKUP [ KIND . POLL_RESPONSE ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Poll Response (NIP-88). Used to respond to polls. Content should be empty. e tag references the poll event, option tag specifies the selected option(s).' ,
suggestedTags : [ 'e (poll event ID)' , 'option (selected option IDs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.POLL_RESPONSE ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'e' , eventId , relay ] ,
[ 'option' , 'opt1' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . USER_STATUS ] : {
. . . KIND_LOOKUP [ KIND . USER_STATUS ] ,
writable : true ,
helpText : {
description : 'User Status (NIP-38). Short status updates from users. Content contains the status message.' ,
suggestedTags : [ 'expiration (optional unix timestamp)' , 't (hashtags)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.USER_STATUS ,
pubkey ,
created_at : timestamp ,
content : 'Working on a new project!' ,
tags : [
[ 'expiration' , ( timestamp + 86400 ) . toString ( ) ] ,
[ 't' , 'status' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . PAYMENT_ADDRESSES ] : {
. . . KIND_LOOKUP [ KIND . PAYMENT_ADDRESSES ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Payment Addresses (NIP-47). Stores payment addresses (e.g., Lightning addresses). Content should be empty. p tags contain payment addresses.' ,
suggestedTags : [ 'p (payment addresses)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.PAYMENT_ADDRESSES ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'p' , 'alice@example.com' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . LABEL ] : {
. . . KIND_LOOKUP [ KIND . LABEL ] ,
writable : true ,
helpText : {
description : 'Label (NIP-32). Used to label events or users. Content contains the label text.' ,
suggestedTags : [ 'e (event IDs to label)' , 'p (pubkeys to label)' , 'L (label namespace)' , 'l (label value)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.LABEL ,
pubkey ,
created_at : timestamp ,
content : 'Important' ,
tags : [
[ 'e' , eventId ] ,
[ 'L' , 'content' ] ,
[ 'l' , 'important' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . REPORT ] : {
. . . KIND_LOOKUP [ KIND . REPORT ] ,
writable : true ,
helpText : {
description : 'Report (NIP-56). Used to report content or users. Content contains the report reason.' ,
suggestedTags : [ 'e (event IDs being reported)' , 'p (pubkeys being reported)' , 'report-type (spam|impersonation|nudity|profanity|illegal|scam)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.REPORT ,
pubkey ,
created_at : timestamp ,
content : 'This content violates community guidelines' ,
tags : [
[ 'e' , eventId ] ,
[ 'report-type' , 'spam' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . RELAY_LIST ] : {
. . . KIND_LOOKUP [ KIND . RELAY_LIST ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Relay List Metadata (NIP-65). Stores relay information and preferences. Content should be empty. relay tags contain relay URLs.' ,
suggestedTags : [ 'relay (relay URLs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.RELAY_LIST ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'relay' , 'wss://relay.example.com' , 'read' , 'write' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . BLOCKED_RELAYS ] : {
. . . KIND_LOOKUP [ KIND . BLOCKED_RELAYS ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Blocked Relays. List of relays to block. Content should be empty. relay tags contain blocked relay URLs.' ,
suggestedTags : [ 'relay (blocked relay URLs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.BLOCKED_RELAYS ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'relay' , 'wss://bad-relay.com' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . FAVORITE_RELAYS ] : {
. . . KIND_LOOKUP [ KIND . FAVORITE_RELAYS ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Favorite Relays. List of favorite relays. Content should be empty. relay tags contain favorite relay URLs.' ,
suggestedTags : [ 'relay (favorite relay URLs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.FAVORITE_RELAYS ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'relay' , 'wss://relay.example.com' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . LOCAL_RELAYS ] : {
. . . KIND_LOOKUP [ KIND . LOCAL_RELAYS ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Local Relays. List of local relays. Content should be empty. relay tags contain local relay URLs.' ,
suggestedTags : [ 'relay (local relay URLs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.LOCAL_RELAYS ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'relay' , 'ws://localhost:8080' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . PIN_LIST ] : {
. . . KIND_LOOKUP [ KIND . PIN_LIST ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Pin List. List of pinned events. Content should be empty. e tags contain event IDs to pin.' ,
suggestedTags : [ 'e (pinned event IDs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.PIN_LIST ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'e' , eventId ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . BOOKMARKS ] : {
. . . KIND_LOOKUP [ KIND . BOOKMARKS ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Bookmarks (NIP-51). List of bookmarked events. Content should be empty. e tags contain bookmarked event IDs.' ,
suggestedTags : [ 'e (bookmarked event IDs)' , 'a (addressable events)' , 't (hashtags for categorization)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.BOOKMARKS ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'e' , eventId , relay ] ,
[ 't' , 'favorites' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . INTEREST_LIST ] : {
. . . KIND_LOOKUP [ KIND . INTEREST_LIST ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Interest List. List of topics or interests. Content should be empty. t tags contain interest topics.' ,
suggestedTags : [ 't (interest topics/hashtags)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.INTEREST_LIST ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 't' , 'nostr' ] ,
[ 't' , 'bitcoin' ] ,
[ 't' , 'technology' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . EMOJI_SET ] : {
. . . KIND_LOOKUP [ KIND . EMOJI_SET ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Emoji Set (NIP-30). Custom emoji set. Content should be empty. emoji tags define custom emojis.' ,
suggestedTags : [ 'emoji (shortcode, URL)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.EMOJI_SET ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'emoji' , 'nostr' , 'https://example.com/emoji/nostr.png' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . EMOJI_PACK ] : {
. . . KIND_LOOKUP [ KIND . EMOJI_PACK ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Emoji Pack (NIP-30). Collection of emoji sets. Content should be empty. a tags reference emoji set events.' ,
suggestedTags : [ 'a (emoji set event references)' , 'd (pack identifier)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.EMOJI_PACK ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'd' , 'my-emoji-pack' ] ,
[ 'a' , ` 10030: ${ pubkey } :emoji-set-1 ` , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . MUTE_LIST ] : {
. . . KIND_LOOKUP [ KIND . MUTE_LIST ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Mute List (NIP-51). List of muted users or content. Content should be empty. p tags contain muted pubkeys, t tags contain muted hashtags.' ,
suggestedTags : [ 'p (muted pubkeys)' , 't (muted hashtags)' , 'e (muted event IDs)' , 'word (muted words)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.MUTE_LIST ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'p' , '3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d' ] ,
[ 't' , 'spam' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . BADGES ] : {
. . . KIND_LOOKUP [ KIND . BADGES ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Badges (NIP-58). Badge definitions. Content should be empty. d tag contains badge identifier, name tag contains badge name.' ,
suggestedTags : [ 'd (badge identifier)' , 'name (badge name)' , 'description' , 'image (badge image URL)' , 'thumb (thumbnail URL)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.BADGES ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'd' , 'early-adopter' ] ,
[ 'name' , 'Early Adopter' ] ,
[ 'description' , 'For users who joined early' ] ,
[ 'image' , 'https://example.com/badge.png' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . FOLLOW_SET ] : {
. . . KIND_LOOKUP [ KIND . FOLLOW_SET ] ,
writable : true ,
requiresContent : false ,
helpText : {
description : 'Follow Set (NIP-51). List of followed users. Content should be empty. p tags contain followed pubkeys.' ,
suggestedTags : [ 'p (followed pubkeys)' , 'relay (optional relay hints)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.FOLLOW_SET ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'p' , '3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d' , relay ] ,
[ 'p' , '67b48a14fb66c60c8f9070bdeb37afdfcc3d08ad01989460448e4081eddda446' , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . HTTP_AUTH ] : {
. . . KIND_LOOKUP [ KIND . HTTP_AUTH ] ,
writable : true ,
helpText : {
description : 'HTTP Auth (NIP-98). Used for HTTP authentication with Nostr. Content contains the HTTP method and URL.' ,
suggestedTags : [ 'u (URL)' , 'method (HTTP method)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.HTTP_AUTH ,
pubkey ,
created_at : timestamp ,
content : 'GET https://example.com/api' ,
tags : [
[ 'u' , 'https://example.com/api' ] ,
[ 'method' , 'GET' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . REPO_ANNOUNCEMENT ] : {
. . . KIND_LOOKUP [ KIND . REPO_ANNOUNCEMENT ] ,
writable : true ,
helpText : {
description : 'Repository Announcement (NIP-34/GRASP). Announces a Git repository. Content contains repository description.' ,
suggestedTags : [ 'd (repository identifier)' , 'name (repository name)' , 'about' , 'web (repository URL)' , 'git (git URL)' , 'relays (relay URLs)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.REPO_ANNOUNCEMENT ,
pubkey ,
created_at : timestamp ,
content : 'A Nostr-based Git repository' ,
tags : [
[ 'd' , 'my-repo' ] ,
[ 'name' , 'My Repository' ] ,
[ 'about' , 'Repository description' ] ,
[ 'web' , 'https://example.com/repo' ] ,
[ 'git' , 'https://git.example.com/repo.git' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . ISSUE ] : {
. . . KIND_LOOKUP [ KIND . ISSUE ] ,
writable : true ,
helpText : {
description : 'Issue (NIP-34/GRASP). Git repository issue. Content contains the issue description.' ,
suggestedTags : [ 'a (repository reference)' , 'title' , 'status (open|closed)' , 'assignee (pubkey)' , 'label' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.ISSUE ,
pubkey ,
created_at : timestamp ,
content : 'Issue description and details' ,
tags : [
[ 'a' , ` 30617: ${ pubkey } :my-repo ` , relay ] ,
[ 'title' , 'Bug Report' ] ,
[ 'status' , 'open' ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . STATUS_OPEN ] : {
. . . KIND_LOOKUP [ KIND . STATUS_OPEN ] ,
writable : true ,
helpText : {
description : 'Status: Open (NIP-34/GRASP). Marks an issue or pull request as open.' ,
suggestedTags : [ 'a (issue/PR reference)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.STATUS_OPEN ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'a' , ` 1621: ${ pubkey } :issue-id ` , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . STATUS_APPLIED ] : {
. . . KIND_LOOKUP [ KIND . STATUS_APPLIED ] ,
writable : true ,
helpText : {
description : 'Status: Applied/Merged/Resolved (NIP-34/GRASP). Marks an issue or pull request as applied, merged, or resolved.' ,
suggestedTags : [ 'a (issue/PR reference)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.STATUS_APPLIED ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'a' , ` 1621: ${ pubkey } :issue-id ` , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . STATUS_CLOSED ] : {
. . . KIND_LOOKUP [ KIND . STATUS_CLOSED ] ,
writable : true ,
helpText : {
description : 'Status: Closed (NIP-34/GRASP). Marks an issue or pull request as closed.' ,
suggestedTags : [ 'a (issue/PR reference)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.STATUS_CLOSED ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'a' , ` 1621: ${ pubkey } :issue-id ` , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
[ KIND . STATUS_DRAFT ] : {
. . . KIND_LOOKUP [ KIND . STATUS_DRAFT ] ,
writable : true ,
helpText : {
description : 'Status: Draft (NIP-34/GRASP). Marks an issue or pull request as draft.' ,
suggestedTags : [ 'a (issue/PR reference)' ]
} ,
exampleJSON : ( pubkey , eventId , relay , timestamp ) = > ( {
kind : KIND.STATUS_DRAFT ,
pubkey ,
created_at : timestamp ,
content : '' ,
tags : [
[ 'a' , ` 1621: ${ pubkey } :issue-id ` , relay ]
] ,
id : '...' ,
sig : '...'
} )
} ,
} ;
/ * *
@ -409,7 +1079,8 @@ export function getKindMetadata(kind: number): KindMetadata {
@@ -409,7 +1079,8 @@ export function getKindMetadata(kind: number): KindMetadata {
* Get all writable kinds for the form
* /
export function getWritableKinds ( ) : Array < { value : number ; label : string } > {
const writableKinds = WRITABLE_KINDS . map ( kind = > {
const allKinds = getAllKinds ( ) ;
const writableKinds = allKinds . map ( ( kind : number ) = > {
const metadata = KIND_METADATA [ kind ] ;
return {
value : kind ,