UNPKG

nostr-tools

Version:
161 lines (159 loc) 4.76 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // nip22.ts var nip22_exports = {}; __export(nip22_exports, { parse: () => parse }); module.exports = __toCommonJS(nip22_exports); var HEX64 = /^[0-9a-fA-F]{64}$/; function parseKind(kind) { if (!kind) return void 0; return /^\d+$/.test(kind) ? parseInt(kind, 10) : kind; } function parseAddressPointer(value, relayUrl) { const idx = value.indexOf(":"); const idx2 = value.indexOf(":", idx + 1); if (idx === -1 || idx2 === -1) return void 0; const kind = parseInt(value.slice(0, idx), 10); if (Number.isNaN(kind)) return void 0; const pubkey = value.slice(idx + 1, idx2); if (!HEX64.test(pubkey)) return void 0; return { kind, pubkey, identifier: value.slice(idx2 + 1), relays: relayUrl ? [relayUrl] : [] }; } function parsePointer(tag) { switch (tag[0]) { case "E": case "e": if (!tag[1] || !HEX64.test(tag[1])) return void 0; return { id: tag[1], relays: tag[2] ? [tag[2]] : [], author: tag[3] && HEX64.test(tag[3]) ? tag[3] : void 0 }; case "A": case "a": if (!tag[1]) return void 0; return parseAddressPointer(tag[1], tag[2]); case "I": case "i": if (!tag[1]) return void 0; return { value: tag[1], hint: tag[2] }; } } function parseQuote(tag) { if (!tag[1]) return void 0; if (tag[1].includes(":")) { return parseAddressPointer(tag[1], tag[2]); } if (!HEX64.test(tag[1])) return void 0; return { id: tag[1], relays: tag[2] ? [tag[2]] : [], author: tag[3] && HEX64.test(tag[3]) ? tag[3] : void 0 }; } function choosePointer(candidates) { return candidates.findLast((candidate) => candidate.tagName === "A" || candidate.tagName === "a")?.pointer || candidates.findLast((candidate) => candidate.tagName === "I" || candidate.tagName === "i")?.pointer || candidates.findLast((candidate) => candidate.tagName === "E" || candidate.tagName === "e")?.pointer; } function inheritRelayHints(pointer, profiles) { if (!pointer || !("id" in pointer) || !pointer.author) return; const author = profiles.find((profile) => profile.pubkey === pointer.author); if (!author || !author.relays) return; if (!pointer.relays) { pointer.relays = []; } author.relays.forEach((url) => { if (pointer.relays.indexOf(url) === -1) pointer.relays.push(url); }); author.relays = pointer.relays; } function parse(event) { const result = { root: void 0, rootKind: void 0, reply: void 0, replyKind: void 0, mentions: [], quotes: [], profiles: [] }; const rootCandidates = []; const replyCandidates = []; for (const tag of event.tags) { if ((tag[0] === "E" || tag[0] === "A" || tag[0] === "I") && tag[1]) { const pointer = parsePointer(tag); if (pointer) rootCandidates.push({ tagName: tag[0], pointer }); continue; } if ((tag[0] === "e" || tag[0] === "a" || tag[0] === "i") && tag[1]) { const pointer = parsePointer(tag); if (pointer) replyCandidates.push({ tagName: tag[0], pointer }); continue; } if (tag[0] === "K") { result.rootKind = parseKind(tag[1]); continue; } if (tag[0] === "k") { result.replyKind = parseKind(tag[1]); continue; } if (tag[0] === "q") { const pointer = parseQuote(tag); if (pointer) result.quotes.push(pointer); continue; } if ((tag[0] === "P" || tag[0] === "p") && tag[1] && HEX64.test(tag[1])) { result.profiles.push({ pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] }); } } result.root = choosePointer(rootCandidates); result.reply = choosePointer(replyCandidates); inheritRelayHints(result.root, result.profiles); inheritRelayHints(result.reply, result.profiles); result.quotes.forEach((pointer) => inheritRelayHints(pointer, result.profiles)); return result; }