@qntx/nostr 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abort-Ba8tDrOI.mjs +38 -0
- package/dist/abort-Ba8tDrOI.mjs.map +1 -0
- package/dist/{builder-BphJa-Y-.d.mts → builder-BWn55Paf.d.mts} +20 -14
- package/dist/{builder-q0VsvnYE.mjs → builder-CyrGKRVP.mjs} +32 -16
- package/dist/builder-CyrGKRVP.mjs.map +1 -0
- package/dist/{client-Bd8B1mYm.mjs → client-BWsX9Cv1.mjs} +354 -195
- package/dist/client-BWsX9Cv1.mjs.map +1 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/core.d.mts +8 -8
- package/dist/core.mjs +8 -9
- package/dist/error-BW7re1UN.d.mts +9 -0
- package/dist/error-B__OMBRY.mjs +14 -0
- package/dist/error-B__OMBRY.mjs.map +1 -0
- package/dist/{error-WEFS-R-4.d.mts → error-CR8Urc84.d.mts} +20 -8
- package/dist/{error-CwBxle6N.mjs → error-DrEIM7FO.mjs} +5 -3
- package/dist/error-DrEIM7FO.mjs.map +1 -0
- package/dist/{event-CzoQEFMF.mjs → event-D8Nfoh4K.mjs} +40 -32
- package/dist/event-D8Nfoh4K.mjs.map +1 -0
- package/dist/{event-B5D2jxt_.d.mts → event-fU3Y01PR.d.mts} +23 -20
- package/dist/{filter-BxwjEkZp.mjs → filter-BQl3GlHt.mjs} +42 -35
- package/dist/filter-BQl3GlHt.mjs.map +1 -0
- package/dist/filter-C0IMByE3.d.mts +37 -0
- package/dist/{gossip-C5RVB1UB.d.mts → gossip-BRQwIM_q.d.mts} +25 -23
- package/dist/{gossip-3xkRRCm_.mjs → gossip-oloDMWEj.mjs} +52 -34
- package/dist/gossip-oloDMWEj.mjs.map +1 -0
- package/dist/gossip.d.mts +1 -1
- package/dist/gossip.mjs +1 -1
- package/dist/{http-6vevbBlu.d.mts → http-C4HwIu4B.d.mts} +7 -7
- package/dist/{http-D2rhokZo.mjs → http-CuazNRIP.mjs} +10 -6
- package/dist/http-CuazNRIP.mjs.map +1 -0
- package/dist/index-B425CAcQ.d.mts +328 -0
- package/dist/index-BVyfUBuG.d.mts +181 -0
- package/dist/{index-BYMnhRIC.d.mts → index-Ba7bJ7DD.d.mts} +68 -50
- package/dist/{index-DaRyjo7O.d.mts → index-Boe8FshM.d.mts} +13 -7
- package/dist/index-CUIvFQdE.d.mts +73 -0
- package/dist/index-JdaS_uce.d.mts +207 -0
- package/dist/index.d.mts +22 -20
- package/dist/index.mjs +19 -18
- package/dist/{key-Dn-aX4x4.mjs → key-Bbtys6o7.mjs} +22 -14
- package/dist/key-Bbtys6o7.mjs.map +1 -0
- package/dist/{key-BiGxGLhg.d.mts → key-BlsYhN1V.d.mts} +9 -6
- package/dist/{kind-BLl4cLOc.mjs → kind-Cxwhhkx8.mjs} +2 -1
- package/dist/kind-Cxwhhkx8.mjs.map +1 -0
- package/dist/{loaders-BNQszDAn.mjs → loaders-o6YXB_Ri.mjs} +329 -305
- package/dist/loaders-o6YXB_Ri.mjs.map +1 -0
- package/dist/loaders.d.mts +3 -3
- package/dist/loaders.mjs +2 -2
- package/dist/memory-C2EVx0_O.mjs +46 -0
- package/dist/memory-C2EVx0_O.mjs.map +1 -0
- package/dist/{memory-BCmhZPek.mjs → memory-index-Do1mz0WF.mjs} +212 -82
- package/dist/memory-index-Do1mz0WF.mjs.map +1 -0
- package/dist/{message-C_Uj-Y-c.mjs → message-DcY6Fi9o.mjs} +38 -24
- package/dist/message-DcY6Fi9o.mjs.map +1 -0
- package/dist/{message-DJC-Jz6T.d.mts → message-iGPIqnn0.d.mts} +15 -8
- package/dist/{nip17-BWq-Kfq5.d.mts → nip17-DNEkz8rM.d.mts} +18 -17
- package/dist/{nip19-D7905oIv.d.mts → nip19-BevCJZsp.d.mts} +23 -3
- package/dist/{nip46-C_DoxiS_.d.mts → nip46-DDV4dC56.d.mts} +13 -12
- package/dist/{nip59-DljW_sYh.d.mts → nip59-zQgdLcEr.d.mts} +28 -25
- package/dist/{nip65-Di5hZRuV.d.mts → nip65-DBfh2smt.d.mts} +8 -3
- package/dist/{nip77-ByxlgoQO.d.mts → nip77-DH4RhS5r.d.mts} +9 -8
- package/dist/nips/blossom.d.mts +37 -37
- package/dist/nips/blossom.mjs +67 -52
- package/dist/nips/blossom.mjs.map +1 -1
- package/dist/nips/nip04.d.mts +2 -3
- package/dist/nips/nip04.mjs +6 -10
- package/dist/nips/nip04.mjs.map +1 -1
- package/dist/nips/nip05.d.mts +37 -43
- package/dist/nips/nip05.mjs +57 -57
- package/dist/nips/nip05.mjs.map +1 -1
- package/dist/nips/nip10.d.mts +18 -19
- package/dist/nips/nip10.mjs +76 -61
- package/dist/nips/nip10.mjs.map +1 -1
- package/dist/nips/nip11.d.mts +9 -8
- package/dist/nips/nip11.mjs +14 -11
- package/dist/nips/nip11.mjs.map +1 -1
- package/dist/nips/nip13.d.mts +9 -9
- package/dist/nips/nip13.mjs +15 -17
- package/dist/nips/nip13.mjs.map +1 -1
- package/dist/nips/nip17.d.mts +1 -1
- package/dist/nips/nip17.mjs +17 -12
- package/dist/nips/nip17.mjs.map +1 -1
- package/dist/nips/nip19.d.mts +1 -1
- package/dist/nips/nip19.mjs +52 -29
- package/dist/nips/nip19.mjs.map +1 -1
- package/dist/nips/nip21.d.mts +5 -6
- package/dist/nips/nip21.mjs +8 -7
- package/dist/nips/nip21.mjs.map +1 -1
- package/dist/nips/nip27.d.mts +7 -8
- package/dist/nips/nip27.mjs +26 -25
- package/dist/nips/nip27.mjs.map +1 -1
- package/dist/nips/nip42.d.mts +5 -6
- package/dist/nips/nip42.mjs +3 -3
- package/dist/nips/nip42.mjs.map +1 -1
- package/dist/nips/nip44.d.mts +24 -7
- package/dist/nips/nip44.mjs +25 -15
- package/dist/nips/nip44.mjs.map +1 -1
- package/dist/nips/nip46.d.mts +1 -1
- package/dist/nips/nip46.mjs +52 -49
- package/dist/nips/nip46.mjs.map +1 -1
- package/dist/nips/nip49.d.mts +8 -7
- package/dist/nips/nip49.mjs +16 -12
- package/dist/nips/nip49.mjs.map +1 -1
- package/dist/nips/nip51.d.mts +25 -27
- package/dist/nips/nip51.mjs +47 -36
- package/dist/nips/nip51.mjs.map +1 -1
- package/dist/nips/nip57.d.mts +12 -13
- package/dist/nips/nip57.mjs +35 -38
- package/dist/nips/nip57.mjs.map +1 -1
- package/dist/nips/nip59.d.mts +1 -1
- package/dist/nips/nip59.mjs +14 -18
- package/dist/nips/nip59.mjs.map +1 -1
- package/dist/nips/nip65.d.mts +1 -1
- package/dist/nips/nip65.mjs +11 -8
- package/dist/nips/nip65.mjs.map +1 -1
- package/dist/nips/nip77.d.mts +1 -1
- package/dist/nips/nip77.mjs +56 -34
- package/dist/nips/nip77.mjs.map +1 -1
- package/dist/nips/nip96.d.mts +21 -12
- package/dist/nips/nip96.mjs +59 -36
- package/dist/nips/nip96.mjs.map +1 -1
- package/dist/nips/nip98.d.mts +12 -12
- package/dist/nips/nip98.mjs +18 -19
- package/dist/nips/nip98.mjs.map +1 -1
- package/dist/{nostr_crypto_wasm_bg-hi5aXi5P.mjs → nostr_crypto_wasm_bg-Czrdty7Q.mjs} +1 -1
- package/dist/nostr_crypto_wasm_bg.wasm +0 -0
- package/dist/{pool-C_j1OmBB.mjs → pool-XmAGaufS.mjs} +611 -487
- package/dist/pool-XmAGaufS.mjs.map +1 -0
- package/dist/pool-tEr7c5bG.d.mts +302 -0
- package/dist/reactive-DDlThDSZ.mjs +324 -0
- package/dist/reactive-DDlThDSZ.mjs.map +1 -0
- package/dist/reactive-DFpqtIf_.d.mts +66 -0
- package/dist/relay.d.mts +5 -4
- package/dist/relay.mjs +2 -2
- package/dist/report-CHld4uWj.mjs +32 -0
- package/dist/report-CHld4uWj.mjs.map +1 -0
- package/dist/{signer-CZ6K6FUc.mjs → signer-CKR9EHce.mjs} +107 -72
- package/dist/signer-CKR9EHce.mjs.map +1 -0
- package/dist/signer.d.mts +3 -3
- package/dist/signer.mjs +3 -2
- package/dist/storage-xXxLGCVb.mjs +1376 -0
- package/dist/storage-xXxLGCVb.mjs.map +1 -0
- package/dist/storage.d.mts +4 -4
- package/dist/storage.mjs +5 -4
- package/dist/store.d.mts +2 -0
- package/dist/store.mjs +2 -0
- package/dist/testing.d.mts +125 -0
- package/dist/testing.mjs +957 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/types-2pCUprRU.d.mts +47 -0
- package/dist/types-CRQEk0Oi.d.mts +19 -0
- package/dist/util-LfQirgDk.mjs +113 -0
- package/dist/util-LfQirgDk.mjs.map +1 -0
- package/dist/wasm.d.mts +4 -4
- package/dist/wasm.mjs +55 -56
- package/dist/wasm.mjs.map +1 -1
- package/dist/websocket-CmeqvAkp.d.mts +27 -0
- package/package.json +31 -9
- package/dist/builder-q0VsvnYE.mjs.map +0 -1
- package/dist/client-Bd8B1mYm.mjs.map +0 -1
- package/dist/error-B49rbDzT.d.mts +0 -7
- package/dist/error-CwBxle6N.mjs.map +0 -1
- package/dist/error-DZEs5OuZ.mjs +0 -24
- package/dist/error-DZEs5OuZ.mjs.map +0 -1
- package/dist/event-CzoQEFMF.mjs.map +0 -1
- package/dist/filter-BxwjEkZp.mjs.map +0 -1
- package/dist/filter-DUEKP3q1.d.mts +0 -40
- package/dist/gossip-3xkRRCm_.mjs.map +0 -1
- package/dist/http-D2rhokZo.mjs.map +0 -1
- package/dist/index-C0C4e-Gn.d.mts +0 -55
- package/dist/index-DgOugrpF.d.mts +0 -275
- package/dist/index-EwL6fHLo.d.mts +0 -267
- package/dist/index-k2YhCgsh.d.mts +0 -57
- package/dist/key-Dn-aX4x4.mjs.map +0 -1
- package/dist/kind-BLl4cLOc.mjs.map +0 -1
- package/dist/loaders-BNQszDAn.mjs.map +0 -1
- package/dist/memory-BCmhZPek.mjs.map +0 -1
- package/dist/message-C_Uj-Y-c.mjs.map +0 -1
- package/dist/pool-C_j1OmBB.mjs.map +0 -1
- package/dist/pool-DhRi7l-b.d.mts +0 -297
- package/dist/signer-CZ6K6FUc.mjs.map +0 -1
- package/dist/storage-DOy0iLRE.mjs +0 -870
- package/dist/storage-DOy0iLRE.mjs.map +0 -1
- package/dist/types-BzyADqnw.d.mts +0 -19
- package/dist/types-Dn24TPFs.d.mts +0 -43
- package/dist/util-6tfLQ9JF.mjs +0 -73
- package/dist/util-6tfLQ9JF.mjs.map +0 -1
package/dist/nips/nip17.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { t as EventBuilder } from "../builder-q0VsvnYE.mjs";
|
|
1
|
+
import { g as NostrError, l as normalizeURL, n as assertHex32, p as EventValidationError } from "../util-LfQirgDk.mjs";
|
|
2
|
+
import { t as Kind } from "../kind-Cxwhhkx8.mjs";
|
|
3
|
+
import { h as Tag } from "../event-D8Nfoh4K.mjs";
|
|
4
|
+
import { t as EventBuilder } from "../builder-CyrGKRVP.mjs";
|
|
6
5
|
import { createGiftWrap, createRumor, createSeal } from "./nip59.mjs";
|
|
7
6
|
//#region src/nips/nip17.ts
|
|
8
7
|
var Nip17Error = class extends NostrError {
|
|
8
|
+
name = "Nip17Error";
|
|
9
9
|
constructor(message, options) {
|
|
10
10
|
super(message, options);
|
|
11
11
|
}
|
|
@@ -16,10 +16,11 @@ function parseDmRelayList(event) {
|
|
|
16
16
|
const out = [];
|
|
17
17
|
const seen = /* @__PURE__ */ new Set();
|
|
18
18
|
for (const tag of event.tags) {
|
|
19
|
-
|
|
19
|
+
const value = tag.at(1);
|
|
20
|
+
if (tag[0] !== "relay" || value === void 0 || value === "") continue;
|
|
20
21
|
let url;
|
|
21
22
|
try {
|
|
22
|
-
url = normalizeURL(
|
|
23
|
+
url = normalizeURL(value);
|
|
23
24
|
} catch {
|
|
24
25
|
continue;
|
|
25
26
|
}
|
|
@@ -46,14 +47,18 @@ function dmRelayListToTags(relays) {
|
|
|
46
47
|
}
|
|
47
48
|
return tags;
|
|
48
49
|
}
|
|
49
|
-
/** Build an unsigned kind:10050 EventBuilder. */
|
|
50
|
+
/** Build an unsigned kind:10050 EventBuilder. NIP-17 requires ≥1 relay tag. */
|
|
50
51
|
function dmRelayListEventBuilder(relays) {
|
|
51
|
-
|
|
52
|
+
const tags = dmRelayListToTags(relays);
|
|
53
|
+
if (tags.length === 0) throw new Nip17Error("DM relay list requires at least one relay");
|
|
54
|
+
return new EventBuilder(Kind.DirectMessageRelaysList, "").tags(tags);
|
|
55
|
+
}
|
|
56
|
+
function isRecipient(value) {
|
|
57
|
+
return typeof value === "object" && value !== null && "pubkey" in value;
|
|
52
58
|
}
|
|
53
59
|
function asRecipientList(input) {
|
|
54
|
-
if (typeof input === "string") return [input];
|
|
55
|
-
|
|
56
|
-
return [input];
|
|
60
|
+
if (typeof input === "string" || isRecipient(input)) return [input];
|
|
61
|
+
return input;
|
|
57
62
|
}
|
|
58
63
|
/** Accept a hex pubkey, a Recipient, or a readonly array of either. Dedup by pubkey. */
|
|
59
64
|
function normalizeRecipients(input) {
|
package/dist/nips/nip17.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip17.mjs","names":["TagBuilder"],"sources":["../../src/nips/nip17.ts"],"sourcesContent":["/**\n * NIP-17: Private Direct Messages
|
|
1
|
+
{"version":3,"file":"nip17.mjs","names":["TagBuilder"],"sources":["../../src/nips/nip17.ts"],"sourcesContent":["import { EventBuilder } from \"../core/builder.ts\";\nimport { EventValidationError, NostrError } from \"../core/error.ts\";\n/**\n * NIP-17: Private Direct Messages. Kind 10050 advertises where gift-wraps should be delivered. Kind\n * 14 rumor construction and per-recipient wrap live here. Envelope primitives live in nip59.ts.\n *\n * @see https://github.com/nostr-protocol/nips/blob/master/17.md\n */\nimport type { Event } from \"../core/event.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport type { Tag } from \"../core/tag.ts\";\nimport { Tag as TagBuilder } from \"../core/tag.ts\";\nimport { assertHex32, normalizeURL } from \"../core/util.ts\";\nimport { createGiftWrap, createRumor, createSeal } from \"./nip59.ts\";\nimport type { Nip59Crypto, Rumor, WrapOptions } from \"./nip59.ts\";\n\nexport class Nip17Error extends NostrError {\n override name = \"Nip17Error\";\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n }\n}\n\nexport type Recipient = {\n readonly pubkey: string;\n readonly relayHint?: string | undefined;\n};\n\nexport type ReplyTo = {\n readonly id: string;\n readonly relayHint?: string | undefined;\n};\n\nexport type ChatMessageOptions = {\n readonly created_at?: number | undefined;\n readonly subject?: string | undefined;\n readonly replyTo?: ReplyTo | undefined;\n};\n\n/** Parse kind:10050 DM relay list (`[\"relay\", url]` tags). */\nexport function parseDmRelayList(event: Pick<Event, \"kind\" | \"tags\">): string[] {\n if (event.kind !== Kind.DirectMessageRelaysList) {\n throw new EventValidationError(\n `expected kind ${Kind.DirectMessageRelaysList}, got ${event.kind}`,\n );\n }\n const out: string[] = [];\n const seen = new Set<string>();\n for (const tag of event.tags) {\n const value = tag.at(1);\n if (tag[0] !== \"relay\" || value === undefined || value === \"\") {\n continue;\n }\n let url: string;\n try {\n url = normalizeURL(value);\n } catch {\n continue;\n }\n if (seen.has(url)) {\n continue;\n }\n seen.add(url);\n out.push(url);\n }\n return out;\n}\n\n/** Encode DM relay URLs as NIP-17 `relay` tags. */\nexport function dmRelayListToTags(relays: ReadonlyArray<string>): Tag[] {\n const tags: Tag[] = [];\n const seen = new Set<string>();\n for (const raw of relays) {\n let url: string;\n try {\n url = normalizeURL(raw);\n } catch {\n continue;\n }\n if (seen.has(url)) {\n continue;\n }\n seen.add(url);\n tags.push([\"relay\", url]);\n }\n return tags;\n}\n\n/** Build an unsigned kind:10050 EventBuilder. NIP-17 requires ≥1 relay tag. */\nexport function dmRelayListEventBuilder(relays: ReadonlyArray<string>): EventBuilder {\n const tags = dmRelayListToTags(relays);\n if (tags.length === 0) {\n throw new Nip17Error(\"DM relay list requires at least one relay\");\n }\n return new EventBuilder(Kind.DirectMessageRelaysList, \"\").tags(tags);\n}\n\nfunction isRecipient(value: unknown): value is Recipient {\n return typeof value === \"object\" && value !== null && \"pubkey\" in value;\n}\n\nfunction asRecipientList(\n input: string | Recipient | ReadonlyArray<string | Recipient>,\n): ReadonlyArray<string | Recipient> {\n if (typeof input === \"string\" || isRecipient(input)) {\n return [input];\n }\n return input;\n}\n\n/** Accept a hex pubkey, a Recipient, or a readonly array of either. Dedup by pubkey. */\nexport function normalizeRecipients(\n input: string | Recipient | ReadonlyArray<string | Recipient>,\n): Recipient[] {\n const out: Recipient[] = [];\n const seen = new Set<string>();\n for (const item of asRecipientList(input)) {\n const rec: Recipient = typeof item === \"string\" ? { pubkey: item } : item;\n const pubkey = assertHex32(rec.pubkey, \"public key\");\n if (seen.has(pubkey)) {\n continue;\n }\n seen.add(pubkey);\n out.push({ pubkey, relayHint: rec.relayHint });\n }\n return out;\n}\n\nexport function buildChatMessageRumor(\n senderPubkey: string,\n recipients: ReadonlyArray<Recipient>,\n content: string,\n opts?: ChatMessageOptions,\n): Rumor {\n if (recipients.length === 0) {\n throw new Nip17Error(\"recipients must not be empty\");\n }\n const tags: Tag[] = [];\n for (const recipient of recipients) {\n const pk = assertHex32(recipient.pubkey, \"public key\");\n tags.push(TagBuilder.p(pk, recipient.relayHint));\n }\n if (opts?.replyTo) {\n // Kind 14 reply e-tag is unmarked: [\"e\", <id>, <relay-url>]\n tags.push(TagBuilder.e(assertHex32(opts.replyTo.id, \"event id\"), opts.replyTo.relayHint ?? \"\"));\n }\n if (opts?.subject !== undefined) {\n tags.push([\"subject\", opts.subject]);\n }\n return createRumor(senderPubkey, {\n kind: Kind.PrivateDirectMessage,\n content,\n tags,\n created_at: opts?.created_at,\n });\n}\n\nfunction wrapTargets(sender: string, recipients: ReadonlyArray<Recipient>): Recipient[] {\n const senderPk = sender.toLowerCase();\n const self = recipients.find((r) => r.pubkey.toLowerCase() === senderPk);\n const out: Recipient[] = [{ pubkey: senderPk, relayHint: self?.relayHint }];\n const seen = new Set<string>([senderPk]);\n for (const recipient of recipients) {\n const pk = recipient.pubkey.toLowerCase();\n if (seen.has(pk)) {\n continue;\n }\n seen.add(pk);\n out.push({ pubkey: pk, relayHint: recipient.relayHint });\n }\n return out;\n}\n\nexport async function wrapDirectMessage(\n crypto: Nip59Crypto,\n recipients: ReadonlyArray<Recipient>,\n rumor: Rumor,\n opts?: Pick<WrapOptions, \"now\" | \"randomInt\" | \"timestamps\" | \"randomize\">,\n): Promise<ReadonlyArray<{ recipient: string; wrap: Event }>> {\n if (recipients.length === 0) {\n throw new Nip17Error(\"recipients must not be empty\");\n }\n const targets = wrapTargets(rumor.pubkey, recipients);\n const out: Array<{ recipient: string; wrap: Event }> = [];\n const timeOpts = opts\n ? {\n now: opts.now,\n randomInt: opts.randomInt,\n timestamps: opts.timestamps,\n randomize: opts.randomize,\n }\n : undefined;\n for (const target of targets) {\n // oxlint-disable-next-line no-await-in-loop -- signer calls stay ordered, one recipient at a time\n const seal = await createSeal(crypto, target.pubkey, rumor, timeOpts);\n const wrap = createGiftWrap(seal, target.pubkey, {\n ...timeOpts,\n relayHint: target.relayHint,\n });\n out.push({ recipient: target.pubkey, wrap });\n }\n return out;\n}\n\nexport function requireDmRelays(pubkey: string, relays: ReadonlyArray<string>): string[] {\n if (relays.length === 0) {\n throw new Nip17Error(`pubkey ${pubkey} is not ready to receive DMs (no kind 10050)`);\n }\n return [...relays];\n}\n"],"mappings":"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"}
|
package/dist/nips/nip19.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as neventEncode, a as NAddr, b as npubEncode, c as NPub, d as Note, f as ProfilePointer, g as naddrEncode, h as encodeBytes, i as EventPointer, l as NSec, m as decodeNostrURI, n as Bech32MaxSize, o as NEvent, p as decode, r as DecodedResult, s as NProfile, t as AddressPointer, u as Nip19Error, v as noteEncode, x as nsecEncode, y as nprofileEncode } from "../nip19-
|
|
1
|
+
import { _ as neventEncode, a as NAddr, b as npubEncode, c as NPub, d as Note, f as ProfilePointer, g as naddrEncode, h as encodeBytes, i as EventPointer, l as NSec, m as decodeNostrURI, n as Bech32MaxSize, o as NEvent, p as decode, r as DecodedResult, s as NProfile, t as AddressPointer, u as Nip19Error, v as noteEncode, x as nsecEncode, y as nprofileEncode } from "../nip19-BevCJZsp.mjs";
|
|
2
2
|
export { AddressPointer, Bech32MaxSize, DecodedResult, EventPointer, NAddr, NEvent, NProfile, NPub, NSec, Nip19Error, Note, ProfilePointer, decode, decodeNostrURI, encodeBytes, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode };
|
package/dist/nips/nip19.mjs
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as NostrError } from "../error-DZEs5OuZ.mjs";
|
|
1
|
+
import { a as hexToBytes, d as utf8Encoder, g as NostrError, i as bytesToHex, n as assertHex32, t as assertByteLength, u as utf8Decoder } from "../util-LfQirgDk.mjs";
|
|
3
2
|
import { bech32 } from "@scure/base";
|
|
4
3
|
//#region src/nips/nip19.ts
|
|
4
|
+
/** Maximum bech32 string length accepted by {@link decode} (NIP-19). */
|
|
5
5
|
const Bech32MaxSize = 5e3;
|
|
6
|
+
/** Error thrown by NIP-19 encoding/decoding failures. */
|
|
6
7
|
var Nip19Error = class extends NostrError {
|
|
8
|
+
name = "Nip19Error";
|
|
7
9
|
constructor(message) {
|
|
8
10
|
super(message);
|
|
9
11
|
}
|
|
10
12
|
};
|
|
11
13
|
function integerToUint8Array(number) {
|
|
12
14
|
const out = /* @__PURE__ */ new Uint8Array(4);
|
|
13
|
-
out
|
|
14
|
-
out[1] = number >> 16 & 255;
|
|
15
|
-
out[2] = number >> 8 & 255;
|
|
16
|
-
out[3] = number & 255;
|
|
15
|
+
new DataView(out.buffer).setUint32(0, number);
|
|
17
16
|
return out;
|
|
18
17
|
}
|
|
19
18
|
function parseTLV(data) {
|
|
@@ -21,21 +20,26 @@ function parseTLV(data) {
|
|
|
21
20
|
let rest = data;
|
|
22
21
|
while (rest.length > 0) {
|
|
23
22
|
if (rest.length < 2) throw new Nip19Error("not enough data to read TLV");
|
|
24
|
-
const t = rest
|
|
25
|
-
const l = rest
|
|
23
|
+
const t = rest.at(0);
|
|
24
|
+
const l = rest.at(1);
|
|
25
|
+
if (t === void 0 || l === void 0) throw new Nip19Error("not enough data to read TLV");
|
|
26
26
|
const v = rest.slice(2, 2 + l);
|
|
27
27
|
rest = rest.slice(2 + l);
|
|
28
28
|
if (v.length < l) throw new Nip19Error(`not enough data to read on TLV ${t}`);
|
|
29
|
-
result[t] = result[t]
|
|
29
|
+
result[t] = result[t] ?? [];
|
|
30
30
|
result[t].push(v);
|
|
31
31
|
}
|
|
32
32
|
return result;
|
|
33
33
|
}
|
|
34
|
+
function assertNip19Kind(kind) {
|
|
35
|
+
if (!Number.isInteger(kind) || kind < 0 || kind > 4294967295) throw new Nip19Error(`invalid kind: ${kind}`);
|
|
36
|
+
}
|
|
34
37
|
function encodeTLV(tlv) {
|
|
35
38
|
const entries = [];
|
|
36
39
|
for (const [t, vs] of Object.entries(tlv).reverse()) for (const v of vs) {
|
|
40
|
+
if (v.length > 255) throw new Nip19Error("TLV value exceeds 255 bytes");
|
|
37
41
|
const entry = new Uint8Array(v.length + 2);
|
|
38
|
-
entry[0] =
|
|
42
|
+
entry[0] = Math.trunc(Number(t));
|
|
39
43
|
entry[1] = v.length;
|
|
40
44
|
entry.set(v, 2);
|
|
41
45
|
entries.push(entry);
|
|
@@ -57,41 +61,51 @@ function encodeBech32(prefix, data) {
|
|
|
57
61
|
function encodeBytes(prefix, bytes) {
|
|
58
62
|
return encodeBech32(prefix, bytes);
|
|
59
63
|
}
|
|
64
|
+
/** Encode a 32-byte secret key as `nsec1…`; throws {@link Nip19Error} on wrong length. */
|
|
60
65
|
function nsecEncode(key) {
|
|
66
|
+
assertByteLength(key, 32, "secret key");
|
|
61
67
|
return encodeBytes("nsec", key);
|
|
62
68
|
}
|
|
69
|
+
/** Encode a hex public key as `npub1…`; throws {@link HexError} on bad hex. */
|
|
63
70
|
function npubEncode(hex) {
|
|
64
|
-
return encodeBytes("npub", hexToBytes(hex));
|
|
71
|
+
return encodeBytes("npub", hexToBytes(assertHex32(hex, "pubkey")));
|
|
65
72
|
}
|
|
73
|
+
/** Encode a hex event id as `note1…`; throws {@link HexError} on bad hex. */
|
|
66
74
|
function noteEncode(hex) {
|
|
67
|
-
return encodeBytes("note", hexToBytes(hex));
|
|
75
|
+
return encodeBytes("note", hexToBytes(assertHex32(hex, "event id")));
|
|
68
76
|
}
|
|
77
|
+
/** Encode a profile pointer as `nprofile1…`. */
|
|
69
78
|
function nprofileEncode(profile) {
|
|
70
79
|
return encodeBech32("nprofile", encodeTLV({
|
|
71
|
-
0: [hexToBytes(profile.pubkey)],
|
|
72
|
-
1: (profile.relays
|
|
80
|
+
0: [hexToBytes(assertHex32(profile.pubkey, "pubkey"))],
|
|
81
|
+
1: (profile.relays ?? []).map((url) => utf8Encoder.encode(url))
|
|
73
82
|
}));
|
|
74
83
|
}
|
|
84
|
+
/** Encode an event pointer as `nevent1…`. */
|
|
75
85
|
function neventEncode(event) {
|
|
76
|
-
|
|
86
|
+
if (event.kind !== void 0) assertNip19Kind(event.kind);
|
|
87
|
+
const kindArray = event.kind === void 0 ? void 0 : integerToUint8Array(event.kind);
|
|
77
88
|
return encodeBech32("nevent", encodeTLV({
|
|
78
|
-
0: [hexToBytes(event.id)],
|
|
79
|
-
1: (event.relays
|
|
80
|
-
2: event.author ? [hexToBytes(event.author)] : [],
|
|
89
|
+
0: [hexToBytes(assertHex32(event.id, "event id"))],
|
|
90
|
+
1: (event.relays ?? []).map((url) => utf8Encoder.encode(url)),
|
|
91
|
+
2: event.author !== void 0 && event.author !== "" ? [hexToBytes(assertHex32(event.author, "author"))] : [],
|
|
81
92
|
3: kindArray ? [kindArray] : []
|
|
82
93
|
}));
|
|
83
94
|
}
|
|
95
|
+
/** Encode an address pointer as `naddr1…`. */
|
|
84
96
|
function naddrEncode(addr) {
|
|
97
|
+
assertNip19Kind(addr.kind);
|
|
85
98
|
const kind = integerToUint8Array(addr.kind);
|
|
86
99
|
return encodeBech32("naddr", encodeTLV({
|
|
87
100
|
0: [utf8Encoder.encode(addr.identifier)],
|
|
88
|
-
1: (addr.relays
|
|
89
|
-
2: [hexToBytes(addr.pubkey)],
|
|
101
|
+
1: (addr.relays ?? []).map((url) => utf8Encoder.encode(url)),
|
|
102
|
+
2: [hexToBytes(assertHex32(addr.pubkey, "pubkey"))],
|
|
90
103
|
3: [kind]
|
|
91
104
|
}));
|
|
92
105
|
}
|
|
106
|
+
/** Decode a NIP-19 bech32 entity; throws {@link Nip19Error} on bad input or unknown prefix. */
|
|
93
107
|
function decode(code) {
|
|
94
|
-
|
|
108
|
+
const { prefix, words } = bech32.decode(code, Bech32MaxSize);
|
|
95
109
|
const data = new Uint8Array(bech32.fromWords(words));
|
|
96
110
|
switch (prefix) {
|
|
97
111
|
case "nprofile": {
|
|
@@ -112,14 +126,17 @@ function decode(code) {
|
|
|
112
126
|
if (tlv[0][0].length !== 32) throw new Nip19Error("TLV 0 should be 32 bytes");
|
|
113
127
|
if (tlv[2]?.[0] && tlv[2][0].length !== 32) throw new Nip19Error("TLV 2 should be 32 bytes");
|
|
114
128
|
if (tlv[3]?.[0] && tlv[3][0].length !== 4) throw new Nip19Error("TLV 3 should be 4 bytes");
|
|
129
|
+
const pointer = {
|
|
130
|
+
id: bytesToHex(tlv[0][0]),
|
|
131
|
+
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
132
|
+
};
|
|
133
|
+
const author = tlv[2]?.[0];
|
|
134
|
+
if (author !== void 0) pointer.author = bytesToHex(author);
|
|
135
|
+
const kind = tlv[3]?.[0];
|
|
136
|
+
if (kind !== void 0) pointer.kind = Number.parseInt(bytesToHex(kind), 16);
|
|
115
137
|
return {
|
|
116
138
|
type: "nevent",
|
|
117
|
-
data:
|
|
118
|
-
id: bytesToHex(tlv[0][0]),
|
|
119
|
-
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
|
120
|
-
author: tlv[2]?.[0] ? bytesToHex(tlv[2][0]) : void 0,
|
|
121
|
-
kind: tlv[3]?.[0] ? Number.parseInt(bytesToHex(tlv[3][0]), 16) : void 0
|
|
122
|
-
}
|
|
139
|
+
data: pointer
|
|
123
140
|
};
|
|
124
141
|
}
|
|
125
142
|
case "naddr": {
|
|
@@ -159,12 +176,18 @@ function decode(code) {
|
|
|
159
176
|
function decodeNostrURI(nip19code) {
|
|
160
177
|
try {
|
|
161
178
|
let code = nip19code;
|
|
162
|
-
if (code.startsWith("nostr:"))
|
|
179
|
+
if (code.startsWith("nostr:")) {
|
|
180
|
+
code = code.slice(6);
|
|
181
|
+
if (code.startsWith("nsec1")) return {
|
|
182
|
+
type: "invalid",
|
|
183
|
+
data: void 0
|
|
184
|
+
};
|
|
185
|
+
}
|
|
163
186
|
return decode(code);
|
|
164
187
|
} catch {
|
|
165
188
|
return {
|
|
166
189
|
type: "invalid",
|
|
167
|
-
data:
|
|
190
|
+
data: void 0
|
|
168
191
|
};
|
|
169
192
|
}
|
|
170
193
|
}
|
package/dist/nips/nip19.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip19.mjs","names":[],"sources":["../../src/nips/nip19.ts"],"sourcesContent":["import { bech32 } from \"@scure/base\";\nimport { NostrError } from \"../core/error.ts\";\nimport { bytesToHex, hexToBytes, utf8Decoder, utf8Encoder } from \"../core/util.ts\";\n\nexport type NProfile = `nprofile1${string}`;\nexport type NEvent = `nevent1${string}`;\nexport type NAddr = `naddr1${string}`;\nexport type NSec = `nsec1${string}`;\nexport type NPub = `npub1${string}`;\nexport type Note = `note1${string}`;\n\nexport const Bech32MaxSize = 5000;\n\nexport type ProfilePointer = {\n pubkey: string;\n relays?: string[];\n};\n\nexport type EventPointer = {\n id: string;\n relays?: string[];\n author?: string;\n kind?: number;\n};\n\nexport type AddressPointer = {\n identifier: string;\n pubkey: string;\n kind: number;\n relays?: string[];\n};\n\nexport type DecodedResult =\n | { type: \"nprofile\"; data: ProfilePointer }\n | { type: \"nevent\"; data: EventPointer }\n | { type: \"naddr\"; data: AddressPointer }\n | { type: \"nsec\"; data: Uint8Array }\n | { type: \"npub\"; data: string }\n | { type: \"note\"; data: string };\n\nexport class Nip19Error extends NostrError {\n constructor(message: string) {\n super(message);\n }\n}\n\ntype TLV = { [t: number]: Uint8Array[] };\n\nfunction integerToUint8Array(number: number): Uint8Array {\n const out = new Uint8Array(4);\n out[0] = (number >> 24) & 0xff;\n out[1] = (number >> 16) & 0xff;\n out[2] = (number >> 8) & 0xff;\n out[3] = number & 0xff;\n return out;\n}\n\nfunction parseTLV(data: Uint8Array): TLV {\n const result: TLV = {};\n let rest = data;\n while (rest.length > 0) {\n if (rest.length < 2) throw new Nip19Error(\"not enough data to read TLV\");\n const t = rest[0]!;\n const l = rest[1]!;\n const v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l) throw new Nip19Error(`not enough data to read on TLV ${t}`);\n result[t] = result[t] || [];\n result[t]!.push(v);\n }\n return result;\n}\n\nfunction encodeTLV(tlv: TLV): Uint8Array {\n const entries: Uint8Array[] = [];\n for (const [t, vs] of Object.entries(tlv).reverse()) {\n for (const v of vs) {\n const entry = new Uint8Array(v.length + 2);\n entry[0] = Number.parseInt(t, 10);\n entry[1] = v.length;\n entry.set(v, 2);\n entries.push(entry);\n }\n }\n let total = 0;\n for (const e of entries) total += e.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const e of entries) {\n out.set(e, offset);\n offset += e.length;\n }\n return out;\n}\n\nfunction encodeBech32<Prefix extends string>(\n prefix: Prefix,\n data: Uint8Array,\n): `${Prefix}1${string}` {\n const words = bech32.toWords(data);\n return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`;\n}\n\nexport function encodeBytes<Prefix extends string>(\n prefix: Prefix,\n bytes: Uint8Array,\n): `${Prefix}1${string}` {\n return encodeBech32(prefix, bytes);\n}\n\nexport function nsecEncode(key: Uint8Array): NSec {\n return encodeBytes(\"nsec\", key);\n}\n\nexport function npubEncode(hex: string): NPub {\n return encodeBytes(\"npub\", hexToBytes(hex));\n}\n\nexport function noteEncode(hex: string): Note {\n return encodeBytes(\"note\", hexToBytes(hex));\n}\n\nexport function nprofileEncode(profile: ProfilePointer): NProfile {\n const data = encodeTLV({\n 0: [hexToBytes(profile.pubkey)],\n 1: (profile.relays || []).map((url) => utf8Encoder.encode(url)),\n });\n return encodeBech32(\"nprofile\", data);\n}\n\nexport function neventEncode(event: EventPointer): NEvent {\n const kindArray = event.kind !== undefined ? integerToUint8Array(event.kind) : undefined;\n const data = encodeTLV({\n 0: [hexToBytes(event.id)],\n 1: (event.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: event.author ? [hexToBytes(event.author)] : [],\n 3: kindArray ? [kindArray] : [],\n });\n return encodeBech32(\"nevent\", data);\n}\n\nexport function naddrEncode(addr: AddressPointer): NAddr {\n const kind = integerToUint8Array(addr.kind);\n const data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes(addr.pubkey)],\n 3: [kind],\n });\n return encodeBech32(\"naddr\", data);\n}\n\nexport function decode(code: string): DecodedResult {\n let { prefix, words } = bech32.decode(code as `${string}1${string}`, Bech32MaxSize);\n const data = new Uint8Array(bech32.fromWords(words));\n\n switch (prefix) {\n case \"nprofile\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) throw new Nip19Error(\"missing TLV 0 for nprofile\");\n if (tlv[0][0].length !== 32) throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nevent\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) throw new Nip19Error(\"missing TLV 0 for nevent\");\n if (tlv[0][0].length !== 32) throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n if (tlv[2]?.[0] && tlv[2][0].length !== 32) throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n if (tlv[3]?.[0] && tlv[3][0].length !== 4) throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"nevent\",\n data: {\n id: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n author: tlv[2]?.[0] ? bytesToHex(tlv[2][0]) : undefined,\n kind: tlv[3]?.[0] ? Number.parseInt(bytesToHex(tlv[3][0]), 16) : undefined,\n },\n };\n }\n case \"naddr\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) throw new Nip19Error(\"missing TLV 0 for naddr\");\n if (!tlv[2]?.[0]) throw new Nip19Error(\"missing TLV 2 for naddr\");\n if (tlv[2][0].length !== 32) throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n if (!tlv[3]?.[0]) throw new Nip19Error(\"missing TLV 3 for naddr\");\n if (tlv[3][0].length !== 4) throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex(tlv[2][0]),\n kind: Number.parseInt(bytesToHex(tlv[3][0]), 16),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nsec\":\n if (data.length !== 32) throw new Nip19Error(\"nsec must be 32 bytes\");\n return { type: \"nsec\", data };\n case \"npub\":\n case \"note\":\n if (data.length !== 32) throw new Nip19Error(`${prefix} must be 32 bytes`);\n return { type: prefix, data: bytesToHex(data) };\n default:\n throw new Nip19Error(`unknown prefix ${prefix}`);\n }\n}\n\n/** Decode `nostr:` URI or bare bech32; returns invalid sentinel instead of throwing. */\nexport function decodeNostrURI(nip19code: string): DecodedResult | { type: \"invalid\"; data: null } {\n try {\n let code = nip19code;\n if (code.startsWith(\"nostr:\")) code = code.slice(6);\n return decode(code);\n } catch {\n return { type: \"invalid\", data: null };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nip19.mjs","names":[],"sources":["../../src/nips/nip19.ts"],"sourcesContent":["import { bech32 } from \"@scure/base\";\n\nimport { NostrError } from \"../core/error.ts\";\nimport {\n assertByteLength,\n assertHex32,\n bytesToHex,\n hexToBytes,\n utf8Decoder,\n utf8Encoder,\n} from \"../core/util.ts\";\n\n/** Bech32 `nprofile1…` string (TLV profile pointer). */\nexport type NProfile = `nprofile1${string}`;\n/** Bech32 `nevent1…` string (TLV event pointer). */\nexport type NEvent = `nevent1${string}`;\n/** Bech32 `naddr1…` string (TLV address pointer). */\nexport type NAddr = `naddr1${string}`;\n/** Bech32 `nsec1…` string (32-byte secret key). */\nexport type NSec = `nsec1${string}`;\n/** Bech32 `npub1…` string (32-byte public key). */\nexport type NPub = `npub1${string}`;\n/** Bech32 `note1…` string (32-byte event id). */\nexport type Note = `note1${string}`;\n\n/** Maximum bech32 string length accepted by {@link decode} (NIP-19). */\nexport const Bech32MaxSize = 5000;\n\n/** Decoded `nprofile` payload: a pubkey plus optional relay hints. */\nexport type ProfilePointer = {\n pubkey: string;\n relays?: string[];\n};\n\n/** Decoded `nevent` payload: an event id plus optional relay/author/kind hints. */\nexport type EventPointer = {\n id: string;\n relays?: string[];\n author?: string;\n kind?: number;\n};\n\n/** Decoded `naddr` payload: a replaceable-event coordinate plus optional relay hints. */\nexport type AddressPointer = {\n identifier: string;\n pubkey: string;\n kind: number;\n relays?: string[];\n};\n\n/** Result of {@link decode}: the bech32 prefix and its decoded payload. */\nexport type DecodedResult =\n | { type: \"nprofile\"; data: ProfilePointer }\n | { type: \"nevent\"; data: EventPointer }\n | { type: \"naddr\"; data: AddressPointer }\n | { type: \"nsec\"; data: Uint8Array }\n | { type: \"npub\"; data: string }\n | { type: \"note\"; data: string };\n\n/** Error thrown by NIP-19 encoding/decoding failures. */\nexport class Nip19Error extends NostrError {\n override name = \"Nip19Error\";\n constructor(message: string) {\n super(message);\n }\n}\n\ntype TLV = Record<number, Uint8Array[]>;\n\nfunction integerToUint8Array(number: number): Uint8Array {\n const out = new Uint8Array(4);\n new DataView(out.buffer).setUint32(0, number);\n return out;\n}\n\nfunction parseTLV(data: Uint8Array): TLV {\n const result: TLV = {};\n let rest = data;\n while (rest.length > 0) {\n if (rest.length < 2) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const t = rest.at(0);\n const l = rest.at(1);\n if (t === undefined || l === undefined) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l) {\n throw new Nip19Error(`not enough data to read on TLV ${t}`);\n }\n result[t] = result[t] ?? [];\n result[t].push(v);\n }\n return result;\n}\n\nfunction assertNip19Kind(kind: number): void {\n if (!Number.isInteger(kind) || kind < 0 || kind > 0xffffffff) {\n throw new Nip19Error(`invalid kind: ${kind}`);\n }\n}\n\nfunction encodeTLV(tlv: TLV): Uint8Array {\n const entries: Uint8Array[] = [];\n for (const [t, vs] of Object.entries(tlv).reverse()) {\n for (const v of vs) {\n if (v.length > 255) {\n throw new Nip19Error(\"TLV value exceeds 255 bytes\");\n }\n const entry = new Uint8Array(v.length + 2);\n entry[0] = Math.trunc(Number(t));\n entry[1] = v.length;\n entry.set(v, 2);\n entries.push(entry);\n }\n }\n let total = 0;\n for (const e of entries) {\n total += e.length;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const e of entries) {\n out.set(e, offset);\n offset += e.length;\n }\n return out;\n}\n\nfunction encodeBech32<Prefix extends string>(\n prefix: Prefix,\n data: Uint8Array,\n): `${Prefix}1${string}` {\n const words = bech32.toWords(data);\n // oxlint-disable-next-line no-unsafe-type-assertion -- bech32 output is `${prefix}1…` by construction\n return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`;\n}\n\nexport function encodeBytes<Prefix extends string>(\n prefix: Prefix,\n bytes: Uint8Array,\n): `${Prefix}1${string}` {\n return encodeBech32(prefix, bytes);\n}\n\n/** Encode a 32-byte secret key as `nsec1…`; throws {@link Nip19Error} on wrong length. */\nexport function nsecEncode(key: Uint8Array): NSec {\n assertByteLength(key, 32, \"secret key\");\n return encodeBytes(\"nsec\", key);\n}\n\n/** Encode a hex public key as `npub1…`; throws {@link HexError} on bad hex. */\nexport function npubEncode(hex: string): NPub {\n return encodeBytes(\"npub\", hexToBytes(assertHex32(hex, \"pubkey\")));\n}\n\n/** Encode a hex event id as `note1…`; throws {@link HexError} on bad hex. */\nexport function noteEncode(hex: string): Note {\n return encodeBytes(\"note\", hexToBytes(assertHex32(hex, \"event id\")));\n}\n\n/** Encode a profile pointer as `nprofile1…`. */\nexport function nprofileEncode(profile: ProfilePointer): NProfile {\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(profile.pubkey, \"pubkey\"))],\n 1: (profile.relays ?? []).map((url) => utf8Encoder.encode(url)),\n });\n return encodeBech32(\"nprofile\", data);\n}\n\n/** Encode an event pointer as `nevent1…`. */\nexport function neventEncode(event: EventPointer): NEvent {\n if (event.kind !== undefined) {\n assertNip19Kind(event.kind);\n }\n const kindArray = event.kind === undefined ? undefined : integerToUint8Array(event.kind);\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(event.id, \"event id\"))],\n 1: (event.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2:\n event.author !== undefined && event.author !== \"\"\n ? [hexToBytes(assertHex32(event.author, \"author\"))]\n : [],\n 3: kindArray ? [kindArray] : [],\n });\n return encodeBech32(\"nevent\", data);\n}\n\n/** Encode an address pointer as `naddr1…`. */\nexport function naddrEncode(addr: AddressPointer): NAddr {\n assertNip19Kind(addr.kind);\n const kind = integerToUint8Array(addr.kind);\n const data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes(assertHex32(addr.pubkey, \"pubkey\"))],\n 3: [kind],\n });\n return encodeBech32(\"naddr\", data);\n}\n\n/** Decode a NIP-19 bech32 entity; throws {@link Nip19Error} on bad input or unknown prefix. */\nexport function decode(code: string): DecodedResult {\n const { prefix, words } = bech32.decode(code, Bech32MaxSize);\n const data = new Uint8Array(bech32.fromWords(words));\n\n switch (prefix) {\n case \"nprofile\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nprofile\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nevent\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nevent\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n if (tlv[2]?.[0] && tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (tlv[3]?.[0] && tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n const pointer: EventPointer = {\n id: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n };\n const author = tlv[2]?.[0];\n if (author !== undefined) {\n pointer.author = bytesToHex(author);\n }\n const kind = tlv[3]?.[0];\n if (kind !== undefined) {\n pointer.kind = Number.parseInt(bytesToHex(kind), 16);\n }\n return { type: \"nevent\", data: pointer };\n }\n case \"naddr\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for naddr\");\n }\n if (!tlv[2]?.[0]) {\n throw new Nip19Error(\"missing TLV 2 for naddr\");\n }\n if (tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (!tlv[3]?.[0]) {\n throw new Nip19Error(\"missing TLV 3 for naddr\");\n }\n if (tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex(tlv[2][0]),\n kind: Number.parseInt(bytesToHex(tlv[3][0]), 16),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nsec\":\n if (data.length !== 32) {\n throw new Nip19Error(\"nsec must be 32 bytes\");\n }\n return { type: \"nsec\", data };\n case \"npub\":\n case \"note\":\n if (data.length !== 32) {\n throw new Nip19Error(`${prefix} must be 32 bytes`);\n }\n return { type: prefix, data: bytesToHex(data) };\n default:\n throw new Nip19Error(`unknown prefix ${prefix}`);\n }\n}\n\n/** Decode `nostr:` URI or bare bech32; returns invalid sentinel instead of throwing. */\nexport function decodeNostrURI(\n nip19code: string,\n): DecodedResult | { type: \"invalid\"; data: undefined } {\n try {\n let code = nip19code;\n if (code.startsWith(\"nostr:\")) {\n code = code.slice(6);\n // NIP-21 excludes nsec from nostr: identifiers.\n if (code.startsWith(\"nsec1\")) {\n return { type: \"invalid\", data: undefined };\n }\n }\n return decode(code);\n } catch {\n return { type: \"invalid\", data: undefined };\n }\n}\n"],"mappings":"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"}
|
package/dist/nips/nip21.d.mts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { r as DecodedResult } from "../nip19-
|
|
1
|
+
import { r as DecodedResult } from "../nip19-BevCJZsp.mjs";
|
|
2
2
|
//#region src/nips/nip21.d.ts
|
|
3
3
|
/** Matches `nostr:<bech32>` (not anchored). */
|
|
4
|
-
declare const NOSTR_URI_REGEX: RegExp;
|
|
5
|
-
type NostrURI = {
|
|
4
|
+
export declare const NOSTR_URI_REGEX: RegExp;
|
|
5
|
+
export type NostrURI = {
|
|
6
6
|
/** Full URI including `nostr:` */
|
|
7
7
|
uri: `nostr:${string}`;
|
|
8
8
|
/** Bech32 entity without prefix */
|
|
9
9
|
value: string;
|
|
10
10
|
decoded: DecodedResult;
|
|
11
11
|
};
|
|
12
|
-
declare function isNostrURI(value: unknown): value is `nostr:${string}`;
|
|
12
|
+
export declare function isNostrURI(value: unknown): value is `nostr:${string}`;
|
|
13
13
|
/** Parse and decode a full `nostr:…` URI. NIP-21 excludes `nsec`. */
|
|
14
|
-
declare function parseNostrURI(uri: string): NostrURI;
|
|
14
|
+
export declare function parseNostrURI(uri: string): NostrURI;
|
|
15
15
|
//#endregion
|
|
16
|
-
export { NOSTR_URI_REGEX, NostrURI, isNostrURI, parseNostrURI };
|
|
17
16
|
//# sourceMappingURL=nip21.d.mts.map
|
package/dist/nips/nip21.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as NostrError } from "../util-LfQirgDk.mjs";
|
|
2
2
|
import { decode } from "./nip19.mjs";
|
|
3
3
|
//#region src/nips/nip21.ts
|
|
4
4
|
/**
|
|
5
5
|
* NIP-21: `nostr:` URI scheme
|
|
6
|
+
*
|
|
6
7
|
* @see https://github.com/nostr-protocol/nips/blob/master/21.md
|
|
7
8
|
*/
|
|
8
9
|
/** Matches `nostr:<bech32>` (not anchored). */
|
|
@@ -14,13 +15,13 @@ function isNostrURI(value) {
|
|
|
14
15
|
}
|
|
15
16
|
/** Parse and decode a full `nostr:…` URI. NIP-21 excludes `nsec`. */
|
|
16
17
|
function parseNostrURI(uri) {
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
19
|
-
if (
|
|
18
|
+
const entity = /^nostr:([a-z0-9]+1[02-9ac-hj-np-z]+)$/i.exec(uri)?.at(1);
|
|
19
|
+
if (entity === void 0) throw new NostrError(`invalid Nostr URI: ${uri}`);
|
|
20
|
+
if (entity.toLowerCase().startsWith("nsec1")) throw new NostrError("NIP-21 identifiers exclude nsec");
|
|
20
21
|
return {
|
|
21
|
-
uri: `nostr:${
|
|
22
|
-
value:
|
|
23
|
-
decoded: decode(
|
|
22
|
+
uri: `nostr:${entity}`,
|
|
23
|
+
value: entity,
|
|
24
|
+
decoded: decode(entity)
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
//#endregion
|
package/dist/nips/nip21.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip21.mjs","names":[],"sources":["../../src/nips/nip21.ts"],"sourcesContent":["/**\n * NIP-21: `nostr:` URI scheme\n * @see https://github.com/nostr-protocol/nips/blob/master/21.md\n */\nimport { NostrError } from \"../core/error.ts\";\nimport { decode
|
|
1
|
+
{"version":3,"file":"nip21.mjs","names":[],"sources":["../../src/nips/nip21.ts"],"sourcesContent":["/**\n * NIP-21: `nostr:` URI scheme\n *\n * @see https://github.com/nostr-protocol/nips/blob/master/21.md\n */\nimport { NostrError } from \"../core/error.ts\";\nimport { decode } from \"./nip19.ts\";\nimport type { DecodedResult } from \"./nip19.ts\";\n\n/** Matches `nostr:<bech32>` (not anchored). */\n// oxlint-disable-next-line no-inferrable-types -- isolatedDeclarations requires the annotation for dts emit\nexport const NOSTR_URI_REGEX: RegExp = /nostr:([a-z0-9]+1[02-9ac-hj-np-z]+)/i;\n\nexport type NostrURI = {\n /** Full URI including `nostr:` */\n uri: `nostr:${string}`;\n /** Bech32 entity without prefix */\n value: string;\n decoded: DecodedResult;\n};\n\nexport function isNostrURI(value: unknown): value is `nostr:${string}` {\n if (typeof value !== \"string\") {\n return false;\n }\n if (!/^nostr:[a-z0-9]+1[02-9ac-hj-np-z]+$/i.test(value)) {\n return false;\n }\n return !value.toLowerCase().startsWith(\"nostr:nsec1\");\n}\n\n/** Parse and decode a full `nostr:…` URI. NIP-21 excludes `nsec`. */\nexport function parseNostrURI(uri: string): NostrURI {\n const match = /^nostr:([a-z0-9]+1[02-9ac-hj-np-z]+)$/i.exec(uri);\n const entity = match?.at(1);\n if (entity === undefined) {\n throw new NostrError(`invalid Nostr URI: ${uri}`);\n }\n if (entity.toLowerCase().startsWith(\"nsec1\")) {\n throw new NostrError(\"NIP-21 identifiers exclude nsec\");\n }\n return {\n uri: `nostr:${entity}`,\n value: entity,\n decoded: decode(entity),\n };\n}\n"],"mappings":";;;;;;;;;AAWA,MAAa,kBAA0B;AAUvC,SAAgB,WAAW,OAA4C;CACrE,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,IAAI,CAAC,uCAAuC,KAAK,KAAK,GACpD,OAAO;CAET,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC,WAAW,aAAa;AACtD;;AAGA,SAAgB,cAAc,KAAuB;CAEnD,MAAM,SADQ,yCAAyC,KAAK,GACzC,CAAC,EAAE,GAAG,CAAC;CAC1B,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,WAAW,sBAAsB,KAAK;CAElD,IAAI,OAAO,YAAY,CAAC,CAAC,WAAW,OAAO,GACzC,MAAM,IAAI,WAAW,iCAAiC;CAExD,OAAO;EACL,KAAK,SAAS;EACd,OAAO;EACP,SAAS,OAAO,MAAM;CACxB;AACF"}
|
package/dist/nips/nip27.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as Event } from "../event-
|
|
2
|
-
import { f as ProfilePointer, i as EventPointer, t as AddressPointer } from "../nip19-
|
|
1
|
+
import { t as Event } from "../event-fU3Y01PR.mjs";
|
|
2
|
+
import { f as ProfilePointer, i as EventPointer, t as AddressPointer } from "../nip19-BevCJZsp.mjs";
|
|
3
3
|
//#region src/nips/nip27.d.ts
|
|
4
|
-
type ContentBlock = {
|
|
4
|
+
export type ContentBlock = {
|
|
5
5
|
type: "text";
|
|
6
6
|
text: string;
|
|
7
7
|
} | {
|
|
@@ -31,12 +31,11 @@ type ContentBlock = {
|
|
|
31
31
|
value: string;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
* Parse note content (or a full event, to pick up emoji tags) into blocks.
|
|
35
|
-
*
|
|
34
|
+
* Parse note content (or a full event, to pick up emoji tags) into blocks. Generator — consume with
|
|
35
|
+
* `for…of` or `[...parseContent(s)]`.
|
|
36
36
|
*/
|
|
37
|
-
declare function parseContent(content: string | Pick<Event, "content" | "tags">): Iterable<ContentBlock>;
|
|
37
|
+
export declare function parseContent(content: string | Pick<Event, "content" | "tags">): Iterable<ContentBlock>;
|
|
38
38
|
/** Collect all content blocks into an array. */
|
|
39
|
-
declare function parseContentBlocks(content: string | Pick<Event, "content" | "tags">): ContentBlock[];
|
|
39
|
+
export declare function parseContentBlocks(content: string | Pick<Event, "content" | "tags">): ContentBlock[];
|
|
40
40
|
//#endregion
|
|
41
|
-
export { ContentBlock, parseContent, parseContentBlocks };
|
|
42
41
|
//# sourceMappingURL=nip27.d.mts.map
|
package/dist/nips/nip27.mjs
CHANGED
|
@@ -4,19 +4,23 @@ const noCharacter = /\W/m;
|
|
|
4
4
|
const noURLCharacter = /[^\w/] |[^\w/]$|$|,| /m;
|
|
5
5
|
const MAX_HASHTAG_LENGTH = 42;
|
|
6
6
|
/**
|
|
7
|
-
* Parse note content (or a full event, to pick up emoji tags) into blocks.
|
|
8
|
-
*
|
|
7
|
+
* Parse note content (or a full event, to pick up emoji tags) into blocks. Generator — consume with
|
|
8
|
+
* `for…of` or `[...parseContent(s)]`.
|
|
9
9
|
*/
|
|
10
10
|
function* parseContent(content) {
|
|
11
|
-
|
|
11
|
+
const emojis = [];
|
|
12
12
|
let text;
|
|
13
13
|
if (typeof content === "string") text = content;
|
|
14
14
|
else {
|
|
15
|
-
for (const tag of content.tags)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
for (const tag of content.tags) {
|
|
16
|
+
const shortcode = tag.at(1);
|
|
17
|
+
const url = tag.at(2);
|
|
18
|
+
if (tag[0] === "emoji" && shortcode !== void 0 && shortcode !== "" && url !== void 0 && url !== "") emojis.push({
|
|
19
|
+
type: "emoji",
|
|
20
|
+
shortcode,
|
|
21
|
+
url
|
|
22
|
+
});
|
|
23
|
+
}
|
|
20
24
|
text = content.content;
|
|
21
25
|
}
|
|
22
26
|
const max = text.length;
|
|
@@ -26,9 +30,9 @@ function* parseContent(content) {
|
|
|
26
30
|
const u = text.indexOf(":", index);
|
|
27
31
|
const h = text.indexOf("#", index);
|
|
28
32
|
if (u === -1 && h === -1) break;
|
|
29
|
-
if (u === -1 || h
|
|
30
|
-
if (h === 0 || h > 0 && text
|
|
31
|
-
const m = text.slice(h + 1, h + MAX_HASHTAG_LENGTH)
|
|
33
|
+
if (u === -1 || h !== -1 && h < u) {
|
|
34
|
+
if (h === 0 || h > 0 && noCharacter.exec(text.at(h - 1) ?? "") !== null) {
|
|
35
|
+
const m = noCharacter.exec(text.slice(h + 1, h + MAX_HASHTAG_LENGTH));
|
|
32
36
|
const end = m ? h + 1 + (m.index ?? 0) : max;
|
|
33
37
|
if (prevIndex !== h) yield {
|
|
34
38
|
type: "text",
|
|
@@ -40,13 +44,13 @@ function* parseContent(content) {
|
|
|
40
44
|
};
|
|
41
45
|
index = end;
|
|
42
46
|
prevIndex = index;
|
|
43
|
-
continue
|
|
47
|
+
continue;
|
|
44
48
|
}
|
|
45
49
|
index = h + 1;
|
|
46
|
-
continue
|
|
50
|
+
continue;
|
|
47
51
|
}
|
|
48
52
|
if (u >= 5 && text.slice(u - 5, u) === "nostr") {
|
|
49
|
-
const m = text.slice(u + 60)
|
|
53
|
+
const m = noCharacter.exec(text.slice(u + 60));
|
|
50
54
|
const end = m ? u + 60 + (m.index ?? 0) : max;
|
|
51
55
|
try {
|
|
52
56
|
const { data, type } = decode(text.slice(u + 1, end));
|
|
@@ -66,9 +70,6 @@ function* parseContent(content) {
|
|
|
66
70
|
case "nsec":
|
|
67
71
|
index = end + 1;
|
|
68
72
|
continue mainloop;
|
|
69
|
-
default:
|
|
70
|
-
index = u + 1;
|
|
71
|
-
continue mainloop;
|
|
72
73
|
}
|
|
73
74
|
if (prevIndex !== u - 5) yield {
|
|
74
75
|
type: "text",
|
|
@@ -80,14 +81,14 @@ function* parseContent(content) {
|
|
|
80
81
|
};
|
|
81
82
|
index = end;
|
|
82
83
|
prevIndex = index;
|
|
83
|
-
continue
|
|
84
|
+
continue;
|
|
84
85
|
} catch {
|
|
85
86
|
index = u + 1;
|
|
86
|
-
continue
|
|
87
|
+
continue;
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
if (u >= 5 && text.slice(u - 5, u) === "https" || u >= 4 && text.slice(u - 4, u) === "http") {
|
|
90
|
-
const m = text.slice(u + 4)
|
|
91
|
+
const m = noURLCharacter.exec(text.slice(u + 4));
|
|
91
92
|
const end = m ? u + 4 + (m.index ?? 0) : max;
|
|
92
93
|
const prefixLen = text[u - 1] === "s" ? 5 : 4;
|
|
93
94
|
try {
|
|
@@ -116,14 +117,14 @@ function* parseContent(content) {
|
|
|
116
117
|
};
|
|
117
118
|
index = end;
|
|
118
119
|
prevIndex = index;
|
|
119
|
-
continue
|
|
120
|
+
continue;
|
|
120
121
|
} catch {
|
|
121
122
|
index = end + 1;
|
|
122
|
-
continue
|
|
123
|
+
continue;
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
if (u >= 3 && text.slice(u - 3, u) === "wss" || u >= 2 && text.slice(u - 2, u) === "ws") {
|
|
126
|
-
const m = text.slice(u + 4)
|
|
127
|
+
const m = noURLCharacter.exec(text.slice(u + 4));
|
|
127
128
|
const end = m ? u + 4 + (m.index ?? 0) : max;
|
|
128
129
|
const prefixLen = text[u - 1] === "s" ? 3 : 2;
|
|
129
130
|
try {
|
|
@@ -139,10 +140,10 @@ function* parseContent(content) {
|
|
|
139
140
|
};
|
|
140
141
|
index = end;
|
|
141
142
|
prevIndex = index;
|
|
142
|
-
continue
|
|
143
|
+
continue;
|
|
143
144
|
} catch {
|
|
144
145
|
index = end + 1;
|
|
145
|
-
continue
|
|
146
|
+
continue;
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
for (const emoji of emojis) {
|
package/dist/nips/nip27.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip27.mjs","names":[],"sources":["../../src/nips/nip27.ts"],"sourcesContent":["/**\n * NIP-27: Text Note References\n * Tokenizes note content into text, nostr: references, URLs, hashtags, media, relays, emoji.\n * @see https://github.com/nostr-protocol/nips/blob/master/27.md\n */\nimport type { Event } from \"../core/event.ts\";\nimport { decode, type AddressPointer, type EventPointer, type ProfilePointer } from \"./nip19.ts\";\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"reference\"; pointer: ProfilePointer | AddressPointer | EventPointer }\n | { type: \"url\"; url: string }\n | { type: \"relay\"; url: string }\n | { type: \"image\"; url: string }\n | { type: \"video\"; url: string }\n | { type: \"audio\"; url: string }\n | { type: \"emoji\"; shortcode: string; url: string }\n | { type: \"hashtag\"; value: string };\n\nconst noCharacter = /\\W/m;\nconst noURLCharacter = /[^\\w/] |[^\\w/]$|$|,| /m;\nconst MAX_HASHTAG_LENGTH = 42;\n\n/**\n * Parse note content (or a full event, to pick up emoji tags) into blocks.\n * Generator — consume with `for…of` or `[...parseContent(s)]`.\n */\nexport function* parseContent(\n content: string | Pick<Event, \"content\" | \"tags\">,\n): Iterable<ContentBlock> {\n let emojis: Array<{ type: \"emoji\"; shortcode: string; url: string }> = [];\n let text: string;\n\n if (typeof content === \"string\") {\n text = content;\n } else {\n for (const tag of content.tags) {\n if (tag[0] === \"emoji\" && tag[1] && tag[2]) {\n emojis.push({ type: \"emoji\", shortcode: tag[1], url: tag[2] });\n }\n }\n text = content.content;\n }\n\n const max = text.length;\n let prevIndex = 0;\n let index = 0;\n\n mainloop: while (index < max) {\n const u = text.indexOf(\":\", index);\n const h = text.indexOf(\"#\", index);\n if (u === -1 && h === -1) break;\n\n if (u === -1 || (h >= 0 && h < u)) {\n // hashtag\n if (h === 0 || (h > 0 && text[h - 1]!.match(noCharacter))) {\n const m = text.slice(h + 1, h + MAX_HASHTAG_LENGTH).match(noCharacter);\n const end = m ? h + 1 + (m.index ?? 0) : max;\n if (prevIndex !== h) yield { type: \"text\", text: text.slice(prevIndex, h) };\n yield { type: \"hashtag\", value: text.slice(h + 1, end) };\n index = end;\n prevIndex = index;\n continue mainloop;\n }\n index = h + 1;\n continue mainloop;\n }\n\n // nostr: references\n if (u >= 5 && text.slice(u - 5, u) === \"nostr\") {\n const m = text.slice(u + 60).match(noCharacter);\n const end = m ? u + 60 + (m.index ?? 0) : max;\n try {\n const { data, type } = decode(text.slice(u + 1, end));\n let pointer: ProfilePointer | AddressPointer | EventPointer | undefined;\n switch (type) {\n case \"npub\":\n pointer = { pubkey: data };\n break;\n case \"note\":\n pointer = { id: data };\n break;\n case \"nprofile\":\n case \"nevent\":\n case \"naddr\":\n pointer = data as ProfilePointer | EventPointer | AddressPointer;\n break;\n case \"nsec\":\n index = end + 1;\n continue mainloop;\n default:\n index = u + 1;\n continue mainloop;\n }\n if (prevIndex !== u - 5) yield { type: \"text\", text: text.slice(prevIndex, u - 5) };\n yield { type: \"reference\", pointer };\n index = end;\n prevIndex = index;\n continue mainloop;\n } catch {\n index = u + 1;\n continue mainloop;\n }\n }\n\n // http(s) URLs\n if (\n (u >= 5 && text.slice(u - 5, u) === \"https\") ||\n (u >= 4 && text.slice(u - 4, u) === \"http\")\n ) {\n const m = text.slice(u + 4).match(noURLCharacter);\n const end = m ? u + 4 + (m.index ?? 0) : max;\n const prefixLen = text[u - 1] === \"s\" ? 5 : 4;\n try {\n const url = new URL(text.slice(u - prefixLen, end));\n if (!url.hostname.includes(\".\")) throw new Error(\"invalid url\");\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: text.slice(prevIndex, u - prefixLen) };\n }\n const path = url.pathname;\n if (/\\.(png|jpe?g|gif|webp|heic|svg)$/i.test(path)) {\n yield { type: \"image\", url: url.toString() };\n } else if (/\\.(mp4|avi|webm|mkv|mov)$/i.test(path)) {\n yield { type: \"video\", url: url.toString() };\n } else if (/\\.(mp3|aac|ogg|opus|wav|flac)$/i.test(path)) {\n yield { type: \"audio\", url: url.toString() };\n } else {\n yield { type: \"url\", url: url.toString() };\n }\n index = end;\n prevIndex = index;\n continue mainloop;\n } catch {\n index = end + 1;\n continue mainloop;\n }\n }\n\n // ws(s) relays\n if ((u >= 3 && text.slice(u - 3, u) === \"wss\") || (u >= 2 && text.slice(u - 2, u) === \"ws\")) {\n const m = text.slice(u + 4).match(noURLCharacter);\n const end = m ? u + 4 + (m.index ?? 0) : max;\n const prefixLen = text[u - 1] === \"s\" ? 3 : 2;\n try {\n const url = new URL(text.slice(u - prefixLen, end));\n if (!url.hostname.includes(\".\")) throw new Error(\"invalid ws url\");\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: text.slice(prevIndex, u - prefixLen) };\n }\n yield { type: \"relay\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue mainloop;\n } catch {\n index = end + 1;\n continue mainloop;\n }\n }\n\n // custom emoji shortcodes :code:\n for (const emoji of emojis) {\n const endColon = u + emoji.shortcode.length + 1;\n if (text[endColon] === \":\" && text.slice(u + 1, endColon) === emoji.shortcode) {\n if (prevIndex !== u) yield { type: \"text\", text: text.slice(prevIndex, u) };\n yield emoji;\n index = endColon + 1;\n prevIndex = index;\n continue mainloop;\n }\n }\n\n index = u + 1;\n }\n\n if (prevIndex !== max) {\n yield { type: \"text\", text: text.slice(prevIndex) };\n }\n}\n\n/** Collect all content blocks into an array. */\nexport function parseContentBlocks(\n content: string | Pick<Event, \"content\" | \"tags\">,\n): ContentBlock[] {\n return [...parseContent(content)];\n}\n"],"mappings":";;AAmBA,MAAM,cAAc;AACpB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;;;;;AAM3B,UAAiB,aACf,SACwB;CACxB,IAAI,SAAmE,CAAC;CACxE,IAAI;CAEJ,IAAI,OAAO,YAAY,UACrB,OAAO;MACF;EACL,KAAK,MAAM,OAAO,QAAQ,MACxB,IAAI,IAAI,OAAO,WAAW,IAAI,MAAM,IAAI,IACtC,OAAO,KAAK;GAAE,MAAM;GAAS,WAAW,IAAI;GAAI,KAAK,IAAI;EAAG,CAAC;EAGjE,OAAO,QAAQ;CACjB;CAEA,MAAM,MAAM,KAAK;CACjB,IAAI,YAAY;CAChB,IAAI,QAAQ;CAEZ,UAAU,OAAO,QAAQ,KAAK;EAC5B,MAAM,IAAI,KAAK,QAAQ,KAAK,KAAK;EACjC,MAAM,IAAI,KAAK,QAAQ,KAAK,KAAK;EACjC,IAAI,MAAM,MAAM,MAAM,IAAI;EAE1B,IAAI,MAAM,MAAO,KAAK,KAAK,IAAI,GAAI;GAEjC,IAAI,MAAM,KAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAE,MAAM,WAAW,GAAI;IACzD,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG,IAAI,kBAAkB,CAAC,CAAC,MAAM,WAAW;IACrE,MAAM,MAAM,IAAI,IAAI,KAAK,EAAE,SAAS,KAAK;IACzC,IAAI,cAAc,GAAG,MAAM;KAAE,MAAM;KAAQ,MAAM,KAAK,MAAM,WAAW,CAAC;IAAE;IAC1E,MAAM;KAAE,MAAM;KAAW,OAAO,KAAK,MAAM,IAAI,GAAG,GAAG;IAAE;IACvD,QAAQ;IACR,YAAY;IACZ,SAAS;GACX;GACA,QAAQ,IAAI;GACZ,SAAS;EACX;EAGA,IAAI,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,SAAS;GAC9C,MAAM,IAAI,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,WAAW;GAC9C,MAAM,MAAM,IAAI,IAAI,MAAM,EAAE,SAAS,KAAK;GAC1C,IAAI;IACF,MAAM,EAAE,MAAM,SAAS,OAAO,KAAK,MAAM,IAAI,GAAG,GAAG,CAAC;IACpD,IAAI;IACJ,QAAQ,MAAR;KACE,KAAK;MACH,UAAU,EAAE,QAAQ,KAAK;MACzB;KACF,KAAK;MACH,UAAU,EAAE,IAAI,KAAK;MACrB;KACF,KAAK;KACL,KAAK;KACL,KAAK;MACH,UAAU;MACV;KACF,KAAK;MACH,QAAQ,MAAM;MACd,SAAS;KACX;MACE,QAAQ,IAAI;MACZ,SAAS;IACb;IACA,IAAI,cAAc,IAAI,GAAG,MAAM;KAAE,MAAM;KAAQ,MAAM,KAAK,MAAM,WAAW,IAAI,CAAC;IAAE;IAClF,MAAM;KAAE,MAAM;KAAa;IAAQ;IACnC,QAAQ;IACR,YAAY;IACZ,SAAS;GACX,QAAQ;IACN,QAAQ,IAAI;IACZ,SAAS;GACX;EACF;EAGA,IACG,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,WACnC,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,QACpC;GACA,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM,cAAc;GAChD,MAAM,MAAM,IAAI,IAAI,KAAK,EAAE,SAAS,KAAK;GACzC,MAAM,YAAY,KAAK,IAAI,OAAO,MAAM,IAAI;GAC5C,IAAI;IACF,MAAM,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,WAAW,GAAG,CAAC;IAClD,IAAI,CAAC,IAAI,SAAS,SAAS,GAAG,GAAG,MAAM,IAAI,MAAM,aAAa;IAC9D,IAAI,cAAc,IAAI,WACpB,MAAM;KAAE,MAAM;KAAQ,MAAM,KAAK,MAAM,WAAW,IAAI,SAAS;IAAE;IAEnE,MAAM,OAAO,IAAI;IACjB,IAAI,oCAAoC,KAAK,IAAI,GAC/C,MAAM;KAAE,MAAM;KAAS,KAAK,IAAI,SAAS;IAAE;SACtC,IAAI,6BAA6B,KAAK,IAAI,GAC/C,MAAM;KAAE,MAAM;KAAS,KAAK,IAAI,SAAS;IAAE;SACtC,IAAI,kCAAkC,KAAK,IAAI,GACpD,MAAM;KAAE,MAAM;KAAS,KAAK,IAAI,SAAS;IAAE;SAE3C,MAAM;KAAE,MAAM;KAAO,KAAK,IAAI,SAAS;IAAE;IAE3C,QAAQ;IACR,YAAY;IACZ,SAAS;GACX,QAAQ;IACN,QAAQ,MAAM;IACd,SAAS;GACX;EACF;EAGA,IAAK,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,SAAW,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,MAAO;GAC3F,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM,cAAc;GAChD,MAAM,MAAM,IAAI,IAAI,KAAK,EAAE,SAAS,KAAK;GACzC,MAAM,YAAY,KAAK,IAAI,OAAO,MAAM,IAAI;GAC5C,IAAI;IACF,MAAM,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,WAAW,GAAG,CAAC;IAClD,IAAI,CAAC,IAAI,SAAS,SAAS,GAAG,GAAG,MAAM,IAAI,MAAM,gBAAgB;IACjE,IAAI,cAAc,IAAI,WACpB,MAAM;KAAE,MAAM;KAAQ,MAAM,KAAK,MAAM,WAAW,IAAI,SAAS;IAAE;IAEnE,MAAM;KAAE,MAAM;KAAS,KAAK,IAAI,SAAS;IAAE;IAC3C,QAAQ;IACR,YAAY;IACZ,SAAS;GACX,QAAQ;IACN,QAAQ,MAAM;IACd,SAAS;GACX;EACF;EAGA,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,WAAW,IAAI,MAAM,UAAU,SAAS;GAC9C,IAAI,KAAK,cAAc,OAAO,KAAK,MAAM,IAAI,GAAG,QAAQ,MAAM,MAAM,WAAW;IAC7E,IAAI,cAAc,GAAG,MAAM;KAAE,MAAM;KAAQ,MAAM,KAAK,MAAM,WAAW,CAAC;IAAE;IAC1E,MAAM;IACN,QAAQ,WAAW;IACnB,YAAY;IACZ,SAAS;GACX;EACF;EAEA,QAAQ,IAAI;CACd;CAEA,IAAI,cAAc,KAChB,MAAM;EAAE,MAAM;EAAQ,MAAM,KAAK,MAAM,SAAS;CAAE;AAEtD;;AAGA,SAAgB,mBACd,SACgB;CAChB,OAAO,CAAC,GAAG,aAAa,OAAO,CAAC;AAClC"}
|
|
1
|
+
{"version":3,"file":"nip27.mjs","names":[],"sources":["../../src/nips/nip27.ts"],"sourcesContent":["/**\n * NIP-27: Text Note References Tokenizes note content into text, nostr: references, URLs, hashtags,\n * media, relays, emoji.\n *\n * @see https://github.com/nostr-protocol/nips/blob/master/27.md\n */\nimport type { Event } from \"../core/event.ts\";\nimport { decode } from \"./nip19.ts\";\nimport type { AddressPointer, EventPointer, ProfilePointer } from \"./nip19.ts\";\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"reference\"; pointer: ProfilePointer | AddressPointer | EventPointer }\n | { type: \"url\"; url: string }\n | { type: \"relay\"; url: string }\n | { type: \"image\"; url: string }\n | { type: \"video\"; url: string }\n | { type: \"audio\"; url: string }\n | { type: \"emoji\"; shortcode: string; url: string }\n | { type: \"hashtag\"; value: string };\n\nconst noCharacter = /\\W/m;\nconst noURLCharacter = /[^\\w/] |[^\\w/]$|$|,| /m;\nconst MAX_HASHTAG_LENGTH = 42;\n\n/**\n * Parse note content (or a full event, to pick up emoji tags) into blocks. Generator — consume with\n * `for…of` or `[...parseContent(s)]`.\n */\nexport function* parseContent(\n content: string | Pick<Event, \"content\" | \"tags\">,\n): Iterable<ContentBlock> {\n const emojis: Array<{ type: \"emoji\"; shortcode: string; url: string }> = [];\n let text: string;\n\n if (typeof content === \"string\") {\n text = content;\n } else {\n for (const tag of content.tags) {\n const shortcode = tag.at(1);\n const url = tag.at(2);\n if (\n tag[0] === \"emoji\" &&\n shortcode !== undefined &&\n shortcode !== \"\" &&\n url !== undefined &&\n url !== \"\"\n ) {\n emojis.push({ type: \"emoji\", shortcode, url });\n }\n }\n text = content.content;\n }\n\n const max = text.length;\n let prevIndex = 0;\n let index = 0;\n\n mainloop: while (index < max) {\n const u = text.indexOf(\":\", index);\n const h = text.indexOf(\"#\", index);\n if (u === -1 && h === -1) {\n break;\n }\n\n if (u === -1 || (h !== -1 && h < u)) {\n // hashtag\n if (h === 0 || (h > 0 && noCharacter.exec(text.at(h - 1) ?? \"\") !== null)) {\n const m = noCharacter.exec(text.slice(h + 1, h + MAX_HASHTAG_LENGTH));\n const end = m ? h + 1 + (m.index ?? 0) : max;\n if (prevIndex !== h) {\n yield { type: \"text\", text: text.slice(prevIndex, h) };\n }\n yield { type: \"hashtag\", value: text.slice(h + 1, end) };\n index = end;\n prevIndex = index;\n continue;\n }\n index = h + 1;\n continue;\n }\n\n // nostr: references\n if (u >= 5 && text.slice(u - 5, u) === \"nostr\") {\n const m = noCharacter.exec(text.slice(u + 60));\n const end = m ? u + 60 + (m.index ?? 0) : max;\n try {\n const { data, type } = decode(text.slice(u + 1, end));\n let pointer: ProfilePointer | AddressPointer | EventPointer | undefined;\n switch (type) {\n case \"npub\":\n pointer = { pubkey: data };\n break;\n case \"note\":\n pointer = { id: data };\n break;\n case \"nprofile\":\n case \"nevent\":\n case \"naddr\":\n pointer = data;\n break;\n case \"nsec\":\n index = end + 1;\n continue mainloop;\n }\n if (prevIndex !== u - 5) {\n yield { type: \"text\", text: text.slice(prevIndex, u - 5) };\n }\n yield { type: \"reference\", pointer };\n index = end;\n prevIndex = index;\n continue;\n } catch {\n index = u + 1;\n continue;\n }\n }\n\n // http(s) URLs\n if (\n (u >= 5 && text.slice(u - 5, u) === \"https\") ||\n (u >= 4 && text.slice(u - 4, u) === \"http\")\n ) {\n const m = noURLCharacter.exec(text.slice(u + 4));\n const end = m ? u + 4 + (m.index ?? 0) : max;\n const prefixLen = text[u - 1] === \"s\" ? 5 : 4;\n try {\n const url = new URL(text.slice(u - prefixLen, end));\n if (!url.hostname.includes(\".\")) {\n throw new Error(\"invalid url\");\n }\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: text.slice(prevIndex, u - prefixLen) };\n }\n const path = url.pathname;\n if (/\\.(png|jpe?g|gif|webp|heic|svg)$/i.test(path)) {\n yield { type: \"image\", url: url.toString() };\n } else if (/\\.(mp4|avi|webm|mkv|mov)$/i.test(path)) {\n yield { type: \"video\", url: url.toString() };\n } else if (/\\.(mp3|aac|ogg|opus|wav|flac)$/i.test(path)) {\n yield { type: \"audio\", url: url.toString() };\n } else {\n yield { type: \"url\", url: url.toString() };\n }\n index = end;\n prevIndex = index;\n continue;\n } catch {\n index = end + 1;\n continue;\n }\n }\n\n // ws(s) relays\n if ((u >= 3 && text.slice(u - 3, u) === \"wss\") || (u >= 2 && text.slice(u - 2, u) === \"ws\")) {\n const m = noURLCharacter.exec(text.slice(u + 4));\n const end = m ? u + 4 + (m.index ?? 0) : max;\n const prefixLen = text[u - 1] === \"s\" ? 3 : 2;\n try {\n const url = new URL(text.slice(u - prefixLen, end));\n if (!url.hostname.includes(\".\")) {\n throw new Error(\"invalid ws url\");\n }\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: text.slice(prevIndex, u - prefixLen) };\n }\n yield { type: \"relay\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n } catch {\n index = end + 1;\n continue;\n }\n }\n\n // custom emoji shortcodes :code:\n for (const emoji of emojis) {\n const endColon = u + emoji.shortcode.length + 1;\n if (text[endColon] === \":\" && text.slice(u + 1, endColon) === emoji.shortcode) {\n if (prevIndex !== u) {\n yield { type: \"text\", text: text.slice(prevIndex, u) };\n }\n yield emoji;\n index = endColon + 1;\n prevIndex = index;\n continue mainloop;\n }\n }\n\n index = u + 1;\n }\n\n if (prevIndex !== max) {\n yield { type: \"text\", text: text.slice(prevIndex) };\n }\n}\n\n/** Collect all content blocks into an array. */\nexport function parseContentBlocks(\n content: string | Pick<Event, \"content\" | \"tags\">,\n): ContentBlock[] {\n return [...parseContent(content)];\n}\n"],"mappings":"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"}
|
package/dist/nips/nip42.d.mts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { n as EventTemplate } from "../event-
|
|
1
|
+
import { n as EventTemplate } from "../event-fU3Y01PR.mjs";
|
|
2
2
|
//#region src/nips/nip42.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* Build an unsigned NIP-42 AUTH event template for the given relay challenge.
|
|
5
|
-
*
|
|
4
|
+
* Build an unsigned NIP-42 AUTH event template for the given relay challenge. Caller must sign with
|
|
5
|
+
* their `NostrSigner` / keys.
|
|
6
6
|
*/
|
|
7
|
-
declare function makeAuthEvent(relayURL: string, challenge: string): EventTemplate;
|
|
7
|
+
export declare function makeAuthEvent(relayURL: string, challenge: string): EventTemplate;
|
|
8
8
|
/** True when a CLOSED reason requests NIP-42 authentication. */
|
|
9
|
-
declare function isAuthRequired(reason: string): boolean;
|
|
9
|
+
export declare function isAuthRequired(reason: string): boolean;
|
|
10
10
|
//#endregion
|
|
11
|
-
export { isAuthRequired, makeAuthEvent };
|
|
12
11
|
//# sourceMappingURL=nip42.d.mts.map
|