lib.ts (3063B)
1 import { 2 KIND_LIST_BLOCKED_RELAYS, 3 KIND_LIST_BOOKMARKS, 4 KIND_LIST_COMMUNITIES, 5 KIND_LIST_DM_RELAYS, 6 KIND_LIST_EMOJIS, 7 KIND_LIST_GOOD_WIKI_AUTHORS, 8 KIND_LIST_GOOD_WIKI_RELAYS, 9 KIND_LIST_INTERESTS, 10 KIND_LIST_MEDIA_FOLLOWS, 11 KIND_LIST_MUTE, 12 KIND_LIST_PINNED_NOTES, 13 KIND_LIST_PUBLIC_CHATS, 14 KIND_LIST_READ_WRITE_RELAYS, 15 KIND_LIST_RELAY_FEEDS, 16 KIND_LIST_SEARCH_RELAYS, 17 KIND_LIST_SIMPLE_GROUPS, 18 type RadrootsList, 19 type RadrootsListEntry, 20 } from "@radroots/events-bindings"; 21 import type { NostrEventFigure, NostrSignedEvent } from "../../types/nostr.js"; 22 import { nostr_event_create } from "../lib.js"; 23 import { tags_list } from "./tags.js"; 24 25 export const NIP51_LIST_KINDS = [ 26 KIND_LIST_MUTE, 27 KIND_LIST_PINNED_NOTES, 28 KIND_LIST_READ_WRITE_RELAYS, 29 KIND_LIST_BOOKMARKS, 30 KIND_LIST_COMMUNITIES, 31 KIND_LIST_PUBLIC_CHATS, 32 KIND_LIST_BLOCKED_RELAYS, 33 KIND_LIST_SEARCH_RELAYS, 34 KIND_LIST_SIMPLE_GROUPS, 35 KIND_LIST_RELAY_FEEDS, 36 KIND_LIST_INTERESTS, 37 KIND_LIST_MEDIA_FOLLOWS, 38 KIND_LIST_EMOJIS, 39 KIND_LIST_DM_RELAYS, 40 KIND_LIST_GOOD_WIKI_AUTHORS, 41 KIND_LIST_GOOD_WIKI_RELAYS, 42 ] as const; 43 44 export type KindRadrootsList = typeof NIP51_LIST_KINDS[number]; 45 46 export const is_nip51_list_kind = (kind: number): kind is KindRadrootsList => 47 NIP51_LIST_KINDS.some(value => value === kind); 48 49 export const nostr_event_list = async ( 50 opts: NostrEventFigure<{ data: RadrootsList; kind: KindRadrootsList }>, 51 ): Promise<NostrSignedEvent | undefined> => { 52 const { data, kind } = opts; 53 if (!is_nip51_list_kind(kind)) return undefined; 54 const tags = await tags_list(data); 55 return nostr_event_create({ 56 ...opts, 57 basis: { 58 kind, 59 content: data.content, 60 tags, 61 }, 62 }); 63 }; 64 65 const is_string_array = (value: unknown): value is string[] => 66 Array.isArray(value) && value.every(item => typeof item === "string"); 67 68 export const list_private_entries_json = (entries: RadrootsListEntry[]): string | undefined => { 69 const tags: string[][] = []; 70 for (const entry of entries) { 71 if (!entry.tag.trim()) return undefined; 72 const first = entry.values[0]; 73 if (!first || !first.trim()) return undefined; 74 tags.push([entry.tag, ...entry.values]); 75 } 76 return JSON.stringify(tags); 77 }; 78 79 export const list_private_entries_parse = (content: string): RadrootsListEntry[] | undefined => { 80 let parsed: unknown; 81 try { 82 parsed = JSON.parse(content); 83 } catch { 84 return undefined; 85 } 86 if (!Array.isArray(parsed)) return undefined; 87 const entries: RadrootsListEntry[] = []; 88 for (const tag of parsed) { 89 if (!is_string_array(tag)) return undefined; 90 if (!tag.length) return undefined; 91 const [name, ...values] = tag; 92 if (!name.trim()) return undefined; 93 const first = values[0]; 94 if (!first || !first.trim()) return undefined; 95 entries.push({ tag: name, values }); 96 } 97 return entries; 98 };