nostr-tools 2.23.11 → 2.24.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/lib/cjs/abstract-pool.js +11 -21
- package/lib/cjs/abstract-pool.js.map +3 -3
- package/lib/cjs/abstract-relay.js +1 -1
- package/lib/cjs/abstract-relay.js.map +2 -2
- package/lib/cjs/core.js +17 -1
- package/lib/cjs/core.js.map +3 -3
- package/lib/cjs/filter.js.map +1 -1
- package/lib/cjs/index.js +124 -123
- package/lib/cjs/index.js.map +4 -4
- package/lib/cjs/kinds.js +17 -1
- package/lib/cjs/kinds.js.map +3 -3
- package/lib/cjs/nip04.js.map +1 -1
- package/lib/cjs/nip10.js +20 -5
- package/lib/cjs/nip10.js.map +3 -3
- package/lib/cjs/nip13.js.map +1 -1
- package/lib/cjs/nip17.js +30 -23
- package/lib/cjs/nip17.js.map +4 -4
- package/lib/cjs/nip18.js +21 -14
- package/lib/cjs/nip18.js.map +4 -4
- package/lib/cjs/nip19.js.map +1 -1
- package/lib/cjs/nip21.js.map +1 -1
- package/lib/cjs/nip22.js +22 -7
- package/lib/cjs/nip22.js.map +3 -3
- package/lib/cjs/nip25.js +21 -14
- package/lib/cjs/nip25.js.map +4 -4
- package/lib/cjs/nip27.js.map +1 -1
- package/lib/cjs/nip28.js +21 -14
- package/lib/cjs/nip28.js.map +4 -4
- package/lib/cjs/nip29.js.map +1 -1
- package/lib/cjs/nip30.js.map +2 -2
- package/lib/cjs/nip42.js.map +2 -2
- package/lib/cjs/nip44.js.map +1 -1
- package/lib/cjs/nip45.js +22 -9
- package/lib/cjs/nip45.js.map +4 -4
- package/lib/cjs/nip46.js +63 -63
- package/lib/cjs/nip46.js.map +4 -4
- package/lib/cjs/nip47.js +25 -18
- package/lib/cjs/nip47.js.map +4 -4
- package/lib/cjs/nip57.js +23 -16
- package/lib/cjs/nip57.js.map +4 -4
- package/lib/cjs/nip58.js.map +2 -2
- package/lib/cjs/nip59.js +16 -7
- package/lib/cjs/nip59.js.map +3 -3
- package/lib/cjs/nip75.js.map +1 -1
- package/lib/cjs/nip94.js.map +1 -1
- package/lib/cjs/nip98.js +23 -16
- package/lib/cjs/nip98.js.map +4 -4
- package/lib/cjs/nip99.js.map +2 -2
- package/lib/cjs/nipb0.js +38 -17
- package/lib/cjs/nipb0.js.map +4 -4
- package/lib/cjs/nipb7.js +13 -7
- package/lib/cjs/nipb7.js.map +2 -2
- package/lib/cjs/pool.js +54 -54
- package/lib/cjs/pool.js.map +4 -4
- package/lib/cjs/pure.js +21 -14
- package/lib/cjs/pure.js.map +4 -4
- package/lib/cjs/references.js.map +1 -1
- package/lib/cjs/relay.js +43 -36
- package/lib/cjs/relay.js.map +4 -4
- package/lib/cjs/signer.js +21 -14
- package/lib/cjs/signer.js.map +4 -4
- package/lib/cjs/utils.js +10 -0
- package/lib/cjs/utils.js.map +2 -2
- package/lib/cjs/wasm.js +16 -2
- package/lib/cjs/wasm.js.map +4 -4
- package/lib/esm/abstract-pool.js +11 -21
- package/lib/esm/abstract-pool.js.map +3 -3
- package/lib/esm/abstract-relay.js +1 -1
- package/lib/esm/abstract-relay.js.map +2 -2
- package/lib/esm/core.js +15 -1
- package/lib/esm/core.js.map +3 -3
- package/lib/esm/filter.js.map +1 -1
- package/lib/esm/index.js +74 -73
- package/lib/esm/index.js.map +4 -4
- package/lib/esm/kinds.js +17 -1
- package/lib/esm/kinds.js.map +3 -3
- package/lib/esm/nip04.js.map +1 -1
- package/lib/esm/nip10.js +18 -5
- package/lib/esm/nip10.js.map +3 -3
- package/lib/esm/nip13.js.map +1 -1
- package/lib/esm/nip17.js +15 -8
- package/lib/esm/nip17.js.map +4 -4
- package/lib/esm/nip18.js +15 -8
- package/lib/esm/nip18.js.map +4 -4
- package/lib/esm/nip19.js.map +1 -1
- package/lib/esm/nip21.js.map +1 -1
- package/lib/esm/nip22.js +20 -7
- package/lib/esm/nip22.js.map +3 -3
- package/lib/esm/nip25.js +15 -8
- package/lib/esm/nip25.js.map +4 -4
- package/lib/esm/nip27.js.map +1 -1
- package/lib/esm/nip28.js +15 -8
- package/lib/esm/nip28.js.map +4 -4
- package/lib/esm/nip29.js.map +1 -1
- package/lib/esm/nip30.js.map +2 -2
- package/lib/esm/nip42.js.map +2 -2
- package/lib/esm/nip44.js.map +1 -1
- package/lib/esm/nip45.js +23 -10
- package/lib/esm/nip45.js.map +4 -4
- package/lib/esm/nip46.js +47 -47
- package/lib/esm/nip46.js.map +4 -4
- package/lib/esm/nip47.js +15 -8
- package/lib/esm/nip47.js.map +4 -4
- package/lib/esm/nip57.js +17 -10
- package/lib/esm/nip57.js.map +4 -4
- package/lib/esm/nip58.js.map +2 -2
- package/lib/esm/nip59.js +10 -1
- package/lib/esm/nip59.js.map +3 -3
- package/lib/esm/nip75.js.map +1 -1
- package/lib/esm/nip94.js.map +1 -1
- package/lib/esm/nip98.js +15 -8
- package/lib/esm/nip98.js.map +4 -4
- package/lib/esm/nip99.js.map +2 -2
- package/lib/esm/nipb0.js +39 -18
- package/lib/esm/nipb0.js.map +4 -4
- package/lib/esm/nipb7.js +13 -7
- package/lib/esm/nipb7.js.map +2 -2
- package/lib/esm/pool.js +47 -47
- package/lib/esm/pool.js.map +4 -4
- package/lib/esm/pure.js +15 -8
- package/lib/esm/pure.js.map +4 -4
- package/lib/esm/references.js.map +1 -1
- package/lib/esm/relay.js +37 -30
- package/lib/esm/relay.js.map +4 -4
- package/lib/esm/signer.js +15 -8
- package/lib/esm/signer.js.map +4 -4
- package/lib/esm/utils.js +10 -0
- package/lib/esm/utils.js.map +2 -2
- package/lib/esm/wasm.js +17 -3
- package/lib/esm/wasm.js.map +4 -4
- package/lib/nostr.bundle.js +73 -70
- package/lib/nostr.bundle.js.map +4 -4
- package/lib/types/abstract-pool.d.ts +6 -4
- package/lib/types/abstract-relay.d.ts +2 -2
- package/lib/types/kinds.d.ts +2 -0
- package/lib/types/nipb0.d.ts +0 -1
- package/lib/types/nipb0.test.d.ts +1 -0
- package/lib/types/nipb7.d.ts +0 -1
- package/lib/types/utils.d.ts +4 -0
- package/package.json +1 -1
- package/lib/types/helpers.d.ts +0 -2
package/lib/esm/signer.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../pure.ts", "../../
|
|
4
|
-
"sourcesContent": ["import { schnorr } from '@noble/curves/secp256k1.js'\nimport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\nimport { Nostr, Event, EventTemplate, UnsignedEvent, VerifiedEvent, verifiedSymbol, validateEvent } from './core.ts'\nimport { sha256 } from '@noble/hashes/sha2.js'\n\nimport { utf8Encoder } from './utils.ts'\n\nclass JS implements Nostr {\n generateSecretKey(): Uint8Array {\n return schnorr.utils.randomSecretKey()\n }\n getPublicKey(secretKey: Uint8Array): string {\n return bytesToHex(schnorr.getPublicKey(secretKey))\n }\n finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {\n const event = t as VerifiedEvent\n event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey))\n event.id = getEventHash(event)\n event.sig = bytesToHex(schnorr.sign(hexToBytes(getEventHash(event)), secretKey))\n event[verifiedSymbol] = true\n return event\n }\n verifyEvent(event: Event): event is VerifiedEvent {\n if (typeof event[verifiedSymbol] === 'boolean') return event[verifiedSymbol]\n\n try {\n const hash = getEventHash(event)\n if (hash !== event.id) {\n event[verifiedSymbol] = false\n return false\n }\n\n const valid = schnorr.verify(hexToBytes(event.sig), hexToBytes(hash), hexToBytes(event.pubkey))\n event[verifiedSymbol] = valid\n return valid\n } catch (err) {\n event[verifiedSymbol] = false\n return false\n }\n }\n}\n\nexport function serializeEvent(evt: UnsignedEvent): string {\n if (!validateEvent(evt)) throw new Error(\"can't serialize event with wrong or missing properties\")\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content])\n}\n\nexport function getEventHash(event: UnsignedEvent): string {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)))\n return bytesToHex(eventHash)\n}\n\nconst i: JS = new JS()\n\nexport const generateSecretKey = i.generateSecretKey\nexport const getPublicKey = i.getPublicKey\nexport const finalizeEvent = i.finalizeEvent\nexport const verifyEvent = i.verifyEvent\nexport * from './core.ts'\n", "
|
|
5
|
-
"mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,cAAAA,aAAY,cAAAC,mBAAkB;;;
|
|
6
|
-
"names": ["bytesToHex", "hexToBytes", "i", "bytesToHex", "hexToBytes"]
|
|
3
|
+
"sources": ["../../pure.ts", "../../utils.ts", "../../core.ts", "../../signer.ts"],
|
|
4
|
+
"sourcesContent": ["import { schnorr } from '@noble/curves/secp256k1.js'\nimport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\nimport { Nostr, Event, EventTemplate, UnsignedEvent, VerifiedEvent, verifiedSymbol, validateEvent } from './core.ts'\nimport { sha256 } from '@noble/hashes/sha2.js'\n\nimport { utf8Encoder } from './utils.ts'\n\nclass JS implements Nostr {\n generateSecretKey(): Uint8Array {\n return schnorr.utils.randomSecretKey()\n }\n getPublicKey(secretKey: Uint8Array): string {\n return bytesToHex(schnorr.getPublicKey(secretKey))\n }\n finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {\n const event = t as VerifiedEvent\n event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey))\n event.id = getEventHash(event)\n event.sig = bytesToHex(schnorr.sign(hexToBytes(getEventHash(event)), secretKey))\n event[verifiedSymbol] = true\n return event\n }\n verifyEvent(event: Event): event is VerifiedEvent {\n if (typeof event[verifiedSymbol] === 'boolean') return event[verifiedSymbol]\n\n try {\n const hash = getEventHash(event)\n if (hash !== event.id) {\n event[verifiedSymbol] = false\n return false\n }\n\n const valid = schnorr.verify(hexToBytes(event.sig), hexToBytes(hash), hexToBytes(event.pubkey))\n event[verifiedSymbol] = valid\n return valid\n } catch (err) {\n event[verifiedSymbol] = false\n return false\n }\n }\n}\n\nexport function serializeEvent(evt: UnsignedEvent): string {\n if (!validateEvent(evt)) throw new Error(\"can't serialize event with wrong or missing properties\")\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content])\n}\n\nexport function getEventHash(event: UnsignedEvent): string {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)))\n return bytesToHex(eventHash)\n}\n\nconst i: JS = new JS()\n\nexport const generateSecretKey = i.generateSecretKey\nexport const getPublicKey = i.getPublicKey\nexport const finalizeEvent = i.finalizeEvent\nexport const verifyEvent = i.verifyEvent\nexport * from './core.ts'\n", "import type { NostrEvent } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n if (p.protocol === 'http:') p.protocol = 'ws:'\n else if (p.protocol === 'https:') p.protocol = 'wss:'\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport function mergeReverseSortedLists(list1: NostrEvent[], list2: NostrEvent[]): NostrEvent[] {\n const result: NostrEvent[] = new Array(list1.length + list2.length)\n result.length = 0\n let i1 = 0\n let i2 = 0\n let sameTimestampIds: string[] = []\n\n while (i1 < list1.length && i2 < list2.length) {\n let next: NostrEvent\n if (list1[i1]?.created_at > list2[i2]?.created_at) {\n next = list1[i1]\n i1++\n } else {\n next = list2[i2]\n i2++\n }\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i1 < list1.length) {\n const next = list1[i1]\n i1++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i2 < list2.length) {\n const next = list2[i2]\n i2++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n return result\n}\n\n/**\n * Checks if a string is a 64-char lowercase hex string as most Nostr ids and pubkeys.\n */\nexport function isHex32(input: string): boolean {\n for (let i = 0; i < 64; i++) {\n let cc = input.charCodeAt(i)\n if (isNaN(cc) || cc < 48 || cc > 102 || (cc > 57 && cc < 97)) {\n return false\n }\n }\n return true\n}\n", "import { isHex32 } from './utils.ts'\n\nexport interface Nostr {\n generateSecretKey(): Uint8Array\n getPublicKey(secretKey: Uint8Array): string\n finalizeEvent(event: EventTemplate, secretKey: Uint8Array): VerifiedEvent\n verifyEvent(event: Event): event is VerifiedEvent\n}\n\n/** Designates a verified event signature. */\nexport const verifiedSymbol = Symbol('verified')\n\nexport type NostrEvent = {\n kind: number\n tags: string[][]\n content: string\n created_at: number\n pubkey: string\n id: string\n sig: string\n [verifiedSymbol]?: boolean\n}\n\nexport type Event = NostrEvent\nexport type EventTemplate = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at'>\nexport type UnsignedEvent = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'>\n\n/** An event whose signature has been verified. */\nexport interface VerifiedEvent extends Event {\n [verifiedSymbol]: true\n}\n\nconst isRecord = (obj: unknown): obj is Record<string, unknown> => obj instanceof Object\n\nexport function validateEvent<T>(event: T): event is T & UnsignedEvent {\n if (!isRecord(event)) return false\n if (typeof event.kind !== 'number') return false\n if (typeof event.content !== 'string') return false\n if (typeof event.created_at !== 'number') return false\n if (typeof event.pubkey !== 'string') return false\n if (!isHex32(event.pubkey)) return false\n\n if (!Array.isArray(event.tags)) return false\n for (let i = 0; i < event.tags.length; i++) {\n let tag = event.tags[i]\n if (!Array.isArray(tag)) return false\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== 'string') return false\n }\n }\n\n return true\n}\n\n/**\n * Sort events in reverse-chronological order by the `created_at` timestamp,\n * and then by the event `id` (lexicographically) in case of ties.\n * This mutates the array.\n */\nexport function sortEvents(events: Event[]): Event[] {\n return events.sort((a: NostrEvent, b: NostrEvent): number => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at\n }\n return a.id.localeCompare(b.id)\n })\n}\n", "import { EventTemplate, VerifiedEvent } from './core.ts'\nimport { finalizeEvent, getPublicKey } from './pure.ts'\n\nexport interface Signer {\n getPublicKey(): Promise<string>\n signEvent(event: EventTemplate): Promise<VerifiedEvent>\n}\n\nexport class PlainKeySigner implements Signer {\n private secretKey: Uint8Array\n\n constructor(secretKey: Uint8Array) {\n this.secretKey = secretKey\n }\n\n async getPublicKey(): Promise<string> {\n return getPublicKey(this.secretKey)\n }\n\n async signEvent(event: EventTemplate): Promise<VerifiedEvent> {\n return finalizeEvent(event, this.secretKey)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["bytesToHex", "hexToBytes", "i", "i", "bytesToHex", "hexToBytes"]
|
|
7
7
|
}
|
package/lib/esm/utils.js
CHANGED
|
@@ -116,12 +116,22 @@ function mergeReverseSortedLists(list1, list2) {
|
|
|
116
116
|
}
|
|
117
117
|
return result;
|
|
118
118
|
}
|
|
119
|
+
function isHex32(input) {
|
|
120
|
+
for (let i = 0; i < 64; i++) {
|
|
121
|
+
let cc = input.charCodeAt(i);
|
|
122
|
+
if (isNaN(cc) || cc < 48 || cc > 102 || cc > 57 && cc < 97) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
119
128
|
export {
|
|
120
129
|
binarySearch,
|
|
121
130
|
bytesToHex,
|
|
122
131
|
hexToBytes,
|
|
123
132
|
insertEventIntoAscendingList,
|
|
124
133
|
insertEventIntoDescendingList,
|
|
134
|
+
isHex32,
|
|
125
135
|
mergeReverseSortedLists,
|
|
126
136
|
normalizeURL,
|
|
127
137
|
utf8Decoder,
|
package/lib/esm/utils.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../utils.ts"],
|
|
4
|
-
"sourcesContent": ["import type { NostrEvent } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n if (p.protocol === 'http:') p.protocol = 'ws:'\n else if (p.protocol === 'https:') p.protocol = 'wss:'\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport function mergeReverseSortedLists(list1: NostrEvent[], list2: NostrEvent[]): NostrEvent[] {\n const result: NostrEvent[] = new Array(list1.length + list2.length)\n result.length = 0\n let i1 = 0\n let i2 = 0\n let sameTimestampIds: string[] = []\n\n while (i1 < list1.length && i2 < list2.length) {\n let next: NostrEvent\n if (list1[i1]?.created_at > list2[i2]?.created_at) {\n next = list1[i1]\n i1++\n } else {\n next = list2[i2]\n i2++\n }\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i1 < list1.length) {\n const next = list1[i1]\n i1++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i2 < list2.length) {\n const next = list2[i2]\n i2++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n return result\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { NostrEvent } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n if (p.protocol === 'http:') p.protocol = 'ws:'\n else if (p.protocol === 'https:') p.protocol = 'wss:'\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport function mergeReverseSortedLists(list1: NostrEvent[], list2: NostrEvent[]): NostrEvent[] {\n const result: NostrEvent[] = new Array(list1.length + list2.length)\n result.length = 0\n let i1 = 0\n let i2 = 0\n let sameTimestampIds: string[] = []\n\n while (i1 < list1.length && i2 < list2.length) {\n let next: NostrEvent\n if (list1[i1]?.created_at > list2[i2]?.created_at) {\n next = list1[i1]\n i1++\n } else {\n next = list2[i2]\n i2++\n }\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i1 < list1.length) {\n const next = list1[i1]\n i1++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i2 < list2.length) {\n const next = list2[i2]\n i2++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n return result\n}\n\n/**\n * Checks if a string is a 64-char lowercase hex string as most Nostr ids and pubkeys.\n */\nexport function isHex32(input: string): boolean {\n for (let i = 0; i < 64; i++) {\n let cc = input.charCodeAt(i)\n if (isNaN(cc) || cc < 48 || cc > 102 || (cc > 57 && cc < 97)) {\n return false\n }\n }\n return true\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/esm/wasm.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
// wasm.ts
|
|
2
|
-
import { bytesToHex } from "@noble/hashes/utils.js";
|
|
2
|
+
import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils.js";
|
|
3
|
+
|
|
4
|
+
// utils.ts
|
|
5
|
+
import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js";
|
|
6
|
+
var utf8Decoder = new TextDecoder("utf-8");
|
|
7
|
+
var utf8Encoder = new TextEncoder();
|
|
8
|
+
function isHex32(input) {
|
|
9
|
+
for (let i2 = 0; i2 < 64; i2++) {
|
|
10
|
+
let cc = input.charCodeAt(i2);
|
|
11
|
+
if (isNaN(cc) || cc < 48 || cc > 102 || cc > 57 && cc < 97) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
3
17
|
|
|
4
18
|
// core.ts
|
|
5
19
|
var verifiedSymbol = Symbol("verified");
|
|
@@ -15,7 +29,7 @@ function validateEvent(event) {
|
|
|
15
29
|
return false;
|
|
16
30
|
if (typeof event.pubkey !== "string")
|
|
17
31
|
return false;
|
|
18
|
-
if (!event.pubkey
|
|
32
|
+
if (!isHex32(event.pubkey))
|
|
19
33
|
return false;
|
|
20
34
|
if (!Array.isArray(event.tags))
|
|
21
35
|
return false;
|
|
@@ -49,7 +63,7 @@ var Wasm = class {
|
|
|
49
63
|
return nw.generateSecretKey();
|
|
50
64
|
}
|
|
51
65
|
getPublicKey(secretKey) {
|
|
52
|
-
return
|
|
66
|
+
return bytesToHex2(nw.getPublicKey(secretKey));
|
|
53
67
|
}
|
|
54
68
|
finalizeEvent(t, secretKey) {
|
|
55
69
|
nw.finalizeEvent(t, secretKey);
|
package/lib/esm/wasm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../wasm.ts", "../../core.ts"],
|
|
4
|
-
"sourcesContent": ["import { bytesToHex } from '@noble/hashes/utils.js'\nimport { Nostr as NostrWasm } from 'nostr-wasm'\nimport { EventTemplate, Event, Nostr, VerifiedEvent, verifiedSymbol } from './core.ts'\n\nlet nw: NostrWasm\n\nexport function setNostrWasm(x: NostrWasm) {\n nw = x\n}\n\nclass Wasm implements Nostr {\n generateSecretKey(): Uint8Array {\n return nw.generateSecretKey()\n }\n getPublicKey(secretKey: Uint8Array): string {\n return bytesToHex(nw.getPublicKey(secretKey))\n }\n finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {\n nw.finalizeEvent(t as any, secretKey)\n return t as VerifiedEvent\n }\n verifyEvent(event: Event): event is VerifiedEvent {\n try {\n nw.verifyEvent(event)\n event[verifiedSymbol] = true\n return true\n } catch (err) {\n return false\n }\n }\n}\n\nconst i: Wasm = new Wasm()\nexport const generateSecretKey = i.generateSecretKey\nexport const getPublicKey = i.getPublicKey\nexport const finalizeEvent = i.finalizeEvent\nexport const verifyEvent = i.verifyEvent\nexport * from './core.ts'\n", "
|
|
5
|
-
"mappings": ";AAAA,SAAS,kBAAkB;;;
|
|
6
|
-
"names": ["i"]
|
|
3
|
+
"sources": ["../../wasm.ts", "../../utils.ts", "../../core.ts"],
|
|
4
|
+
"sourcesContent": ["import { bytesToHex } from '@noble/hashes/utils.js'\nimport { Nostr as NostrWasm } from 'nostr-wasm'\nimport { EventTemplate, Event, Nostr, VerifiedEvent, verifiedSymbol } from './core.ts'\n\nlet nw: NostrWasm\n\nexport function setNostrWasm(x: NostrWasm) {\n nw = x\n}\n\nclass Wasm implements Nostr {\n generateSecretKey(): Uint8Array {\n return nw.generateSecretKey()\n }\n getPublicKey(secretKey: Uint8Array): string {\n return bytesToHex(nw.getPublicKey(secretKey))\n }\n finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {\n nw.finalizeEvent(t as any, secretKey)\n return t as VerifiedEvent\n }\n verifyEvent(event: Event): event is VerifiedEvent {\n try {\n nw.verifyEvent(event)\n event[verifiedSymbol] = true\n return true\n } catch (err) {\n return false\n }\n }\n}\n\nconst i: Wasm = new Wasm()\nexport const generateSecretKey = i.generateSecretKey\nexport const getPublicKey = i.getPublicKey\nexport const finalizeEvent = i.finalizeEvent\nexport const verifyEvent = i.verifyEvent\nexport * from './core.ts'\n", "import type { NostrEvent } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n if (p.protocol === 'http:') p.protocol = 'ws:'\n else if (p.protocol === 'https:') p.protocol = 'wss:'\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: NostrEvent[], event: NostrEvent): NostrEvent[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport function mergeReverseSortedLists(list1: NostrEvent[], list2: NostrEvent[]): NostrEvent[] {\n const result: NostrEvent[] = new Array(list1.length + list2.length)\n result.length = 0\n let i1 = 0\n let i2 = 0\n let sameTimestampIds: string[] = []\n\n while (i1 < list1.length && i2 < list2.length) {\n let next: NostrEvent\n if (list1[i1]?.created_at > list2[i2]?.created_at) {\n next = list1[i1]\n i1++\n } else {\n next = list2[i2]\n i2++\n }\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i1 < list1.length) {\n const next = list1[i1]\n i1++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n while (i2 < list2.length) {\n const next = list2[i2]\n i2++\n\n if (result.length > 0 && result[result.length - 1].created_at === next.created_at) {\n if (sameTimestampIds.includes(next.id)) continue\n } else {\n sameTimestampIds.length = 0\n }\n result.push(next)\n sameTimestampIds.push(next.id)\n }\n\n return result\n}\n\n/**\n * Checks if a string is a 64-char lowercase hex string as most Nostr ids and pubkeys.\n */\nexport function isHex32(input: string): boolean {\n for (let i = 0; i < 64; i++) {\n let cc = input.charCodeAt(i)\n if (isNaN(cc) || cc < 48 || cc > 102 || (cc > 57 && cc < 97)) {\n return false\n }\n }\n return true\n}\n", "import { isHex32 } from './utils.ts'\n\nexport interface Nostr {\n generateSecretKey(): Uint8Array\n getPublicKey(secretKey: Uint8Array): string\n finalizeEvent(event: EventTemplate, secretKey: Uint8Array): VerifiedEvent\n verifyEvent(event: Event): event is VerifiedEvent\n}\n\n/** Designates a verified event signature. */\nexport const verifiedSymbol = Symbol('verified')\n\nexport type NostrEvent = {\n kind: number\n tags: string[][]\n content: string\n created_at: number\n pubkey: string\n id: string\n sig: string\n [verifiedSymbol]?: boolean\n}\n\nexport type Event = NostrEvent\nexport type EventTemplate = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at'>\nexport type UnsignedEvent = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'>\n\n/** An event whose signature has been verified. */\nexport interface VerifiedEvent extends Event {\n [verifiedSymbol]: true\n}\n\nconst isRecord = (obj: unknown): obj is Record<string, unknown> => obj instanceof Object\n\nexport function validateEvent<T>(event: T): event is T & UnsignedEvent {\n if (!isRecord(event)) return false\n if (typeof event.kind !== 'number') return false\n if (typeof event.content !== 'string') return false\n if (typeof event.created_at !== 'number') return false\n if (typeof event.pubkey !== 'string') return false\n if (!isHex32(event.pubkey)) return false\n\n if (!Array.isArray(event.tags)) return false\n for (let i = 0; i < event.tags.length; i++) {\n let tag = event.tags[i]\n if (!Array.isArray(tag)) return false\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== 'string') return false\n }\n }\n\n return true\n}\n\n/**\n * Sort events in reverse-chronological order by the `created_at` timestamp,\n * and then by the event `id` (lexicographically) in case of ties.\n * This mutates the array.\n */\nexport function sortEvents(events: Event[]): Event[] {\n return events.sort((a: NostrEvent, b: NostrEvent): number => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at\n }\n return a.id.localeCompare(b.id)\n })\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,cAAAA,mBAAkB;;;ACK3B,SAAS,YAAY,kBAAkB;AAHhC,IAAM,cAA2B,IAAI,YAAY,OAAO;AACxD,IAAM,cAA2B,IAAI,YAAY;AA8HjD,SAAS,QAAQ,OAAwB;AAC9C,WAASC,KAAI,GAAGA,KAAI,IAAIA,MAAK;AAC3B,QAAI,KAAK,MAAM,WAAWA,EAAC;AAC3B,QAAI,MAAM,EAAE,KAAK,KAAK,MAAM,KAAK,OAAQ,KAAK,MAAM,KAAK,IAAK;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AC/HO,IAAM,iBAAiB,OAAO,UAAU;AAsB/C,IAAM,WAAW,CAAC,QAAiD,eAAe;AAE3E,SAAS,cAAiB,OAAsC;AACrE,MAAI,CAAC,SAAS,KAAK;AAAG,WAAO;AAC7B,MAAI,OAAO,MAAM,SAAS;AAAU,WAAO;AAC3C,MAAI,OAAO,MAAM,YAAY;AAAU,WAAO;AAC9C,MAAI,OAAO,MAAM,eAAe;AAAU,WAAO;AACjD,MAAI,OAAO,MAAM,WAAW;AAAU,WAAO;AAC7C,MAAI,CAAC,QAAQ,MAAM,MAAM;AAAG,WAAO;AAEnC,MAAI,CAAC,MAAM,QAAQ,MAAM,IAAI;AAAG,WAAO;AACvC,WAASC,KAAI,GAAGA,KAAI,MAAM,KAAK,QAAQA,MAAK;AAC1C,QAAI,MAAM,MAAM,KAAKA;AACrB,QAAI,CAAC,MAAM,QAAQ,GAAG;AAAG,aAAO;AAChC,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,OAAO,IAAI,OAAO;AAAU,eAAO;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,WAAW,QAA0B;AACnD,SAAO,OAAO,KAAK,CAAC,GAAe,MAA0B;AAC3D,QAAI,EAAE,eAAe,EAAE,YAAY;AACjC,aAAO,EAAE,aAAa,EAAE;AAAA,IAC1B;AACA,WAAO,EAAE,GAAG,cAAc,EAAE,EAAE;AAAA,EAChC,CAAC;AACH;;;AF9DA,IAAI;AAEG,SAAS,aAAa,GAAc;AACzC,OAAK;AACP;AAEA,IAAM,OAAN,MAA4B;AAAA,EAC1B,oBAAgC;AAC9B,WAAO,GAAG,kBAAkB;AAAA,EAC9B;AAAA,EACA,aAAa,WAA+B;AAC1C,WAAOC,YAAW,GAAG,aAAa,SAAS,CAAC;AAAA,EAC9C;AAAA,EACA,cAAc,GAAkB,WAAsC;AACpE,OAAG,cAAc,GAAU,SAAS;AACpC,WAAO;AAAA,EACT;AAAA,EACA,YAAY,OAAsC;AAChD,QAAI;AACF,SAAG,YAAY,KAAK;AACpB,YAAM,kBAAkB;AACxB,aAAO;AAAA,IACT,SAAS,KAAP;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,IAAM,IAAU,IAAI,KAAK;AAClB,IAAM,oBAAoB,EAAE;AAC5B,IAAM,eAAe,EAAE;AACvB,IAAM,gBAAgB,EAAE;AACxB,IAAM,cAAc,EAAE;",
|
|
6
|
+
"names": ["bytesToHex", "i", "i", "bytesToHex"]
|
|
7
7
|
}
|
package/lib/nostr.bundle.js
CHANGED
|
@@ -2228,44 +2228,6 @@ var NostrTools = (() => {
|
|
|
2228
2228
|
};
|
|
2229
2229
|
})();
|
|
2230
2230
|
|
|
2231
|
-
// core.ts
|
|
2232
|
-
var verifiedSymbol = Symbol("verified");
|
|
2233
|
-
var isRecord = (obj) => obj instanceof Object;
|
|
2234
|
-
function validateEvent(event) {
|
|
2235
|
-
if (!isRecord(event))
|
|
2236
|
-
return false;
|
|
2237
|
-
if (typeof event.kind !== "number")
|
|
2238
|
-
return false;
|
|
2239
|
-
if (typeof event.content !== "string")
|
|
2240
|
-
return false;
|
|
2241
|
-
if (typeof event.created_at !== "number")
|
|
2242
|
-
return false;
|
|
2243
|
-
if (typeof event.pubkey !== "string")
|
|
2244
|
-
return false;
|
|
2245
|
-
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
|
2246
|
-
return false;
|
|
2247
|
-
if (!Array.isArray(event.tags))
|
|
2248
|
-
return false;
|
|
2249
|
-
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
|
2250
|
-
let tag = event.tags[i2];
|
|
2251
|
-
if (!Array.isArray(tag))
|
|
2252
|
-
return false;
|
|
2253
|
-
for (let j = 0; j < tag.length; j++) {
|
|
2254
|
-
if (typeof tag[j] !== "string")
|
|
2255
|
-
return false;
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
return true;
|
|
2259
|
-
}
|
|
2260
|
-
function sortEvents(events) {
|
|
2261
|
-
return events.sort((a, b) => {
|
|
2262
|
-
if (a.created_at !== b.created_at) {
|
|
2263
|
-
return b.created_at - a.created_at;
|
|
2264
|
-
}
|
|
2265
|
-
return a.id.localeCompare(b.id);
|
|
2266
|
-
});
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
2231
|
// utils.ts
|
|
2270
2232
|
var utils_exports = {};
|
|
2271
2233
|
__export(utils_exports, {
|
|
@@ -2274,6 +2236,7 @@ var NostrTools = (() => {
|
|
|
2274
2236
|
hexToBytes: () => hexToBytes,
|
|
2275
2237
|
insertEventIntoAscendingList: () => insertEventIntoAscendingList,
|
|
2276
2238
|
insertEventIntoDescendingList: () => insertEventIntoDescendingList,
|
|
2239
|
+
isHex32: () => isHex32,
|
|
2277
2240
|
mergeReverseSortedLists: () => mergeReverseSortedLists,
|
|
2278
2241
|
normalizeURL: () => normalizeURL,
|
|
2279
2242
|
utf8Decoder: () => utf8Decoder,
|
|
@@ -2395,6 +2358,53 @@ var NostrTools = (() => {
|
|
|
2395
2358
|
}
|
|
2396
2359
|
return result;
|
|
2397
2360
|
}
|
|
2361
|
+
function isHex32(input) {
|
|
2362
|
+
for (let i2 = 0; i2 < 64; i2++) {
|
|
2363
|
+
let cc = input.charCodeAt(i2);
|
|
2364
|
+
if (isNaN(cc) || cc < 48 || cc > 102 || cc > 57 && cc < 97) {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
return true;
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
// core.ts
|
|
2372
|
+
var verifiedSymbol = Symbol("verified");
|
|
2373
|
+
var isRecord = (obj) => obj instanceof Object;
|
|
2374
|
+
function validateEvent(event) {
|
|
2375
|
+
if (!isRecord(event))
|
|
2376
|
+
return false;
|
|
2377
|
+
if (typeof event.kind !== "number")
|
|
2378
|
+
return false;
|
|
2379
|
+
if (typeof event.content !== "string")
|
|
2380
|
+
return false;
|
|
2381
|
+
if (typeof event.created_at !== "number")
|
|
2382
|
+
return false;
|
|
2383
|
+
if (typeof event.pubkey !== "string")
|
|
2384
|
+
return false;
|
|
2385
|
+
if (!isHex32(event.pubkey))
|
|
2386
|
+
return false;
|
|
2387
|
+
if (!Array.isArray(event.tags))
|
|
2388
|
+
return false;
|
|
2389
|
+
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
|
2390
|
+
let tag = event.tags[i2];
|
|
2391
|
+
if (!Array.isArray(tag))
|
|
2392
|
+
return false;
|
|
2393
|
+
for (let j = 0; j < tag.length; j++) {
|
|
2394
|
+
if (typeof tag[j] !== "string")
|
|
2395
|
+
return false;
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
return true;
|
|
2399
|
+
}
|
|
2400
|
+
function sortEvents(events) {
|
|
2401
|
+
return events.sort((a, b) => {
|
|
2402
|
+
if (a.created_at !== b.created_at) {
|
|
2403
|
+
return b.created_at - a.created_at;
|
|
2404
|
+
}
|
|
2405
|
+
return a.id.localeCompare(b.id);
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2398
2408
|
|
|
2399
2409
|
// pure.ts
|
|
2400
2410
|
var JS = class {
|
|
@@ -2499,6 +2509,7 @@ var NostrTools = (() => {
|
|
|
2499
2509
|
Emojisets: () => Emojisets,
|
|
2500
2510
|
EncryptedDirectMessage: () => EncryptedDirectMessage,
|
|
2501
2511
|
EventDeletion: () => EventDeletion,
|
|
2512
|
+
FavoriteFollowSets: () => FavoriteFollowSets,
|
|
2502
2513
|
FavoritePodcasts: () => FavoritePodcasts,
|
|
2503
2514
|
FavoriteRelays: () => FavoriteRelays,
|
|
2504
2515
|
FedimintAnnouncement: () => FedimintAnnouncement,
|
|
@@ -2771,6 +2782,7 @@ var NostrTools = (() => {
|
|
|
2771
2782
|
var InterestsList = 10015;
|
|
2772
2783
|
var NutZapInfo = 10019;
|
|
2773
2784
|
var MediaFollows = 10020;
|
|
2785
|
+
var FavoriteFollowSets = 10021;
|
|
2774
2786
|
var UserEmojiList = 10030;
|
|
2775
2787
|
var DecoupledKeyAnnouncement = 10044;
|
|
2776
2788
|
var DirectMessageRelaysList = 10050;
|
|
@@ -3370,7 +3382,7 @@ var NostrTools = (() => {
|
|
|
3370
3382
|
case "EVENT": {
|
|
3371
3383
|
const so = this.openSubs.get(data[1]);
|
|
3372
3384
|
const event = data[2];
|
|
3373
|
-
if (
|
|
3385
|
+
if (matchFilters(so.filters, event) && this.verifyEvent(event, this.url)) {
|
|
3374
3386
|
so.onevent(event);
|
|
3375
3387
|
} else {
|
|
3376
3388
|
so.oninvalidevent?.(event);
|
|
@@ -3543,12 +3555,6 @@ var NostrTools = (() => {
|
|
|
3543
3555
|
}
|
|
3544
3556
|
};
|
|
3545
3557
|
|
|
3546
|
-
// helpers.ts
|
|
3547
|
-
var alwaysTrue = (t) => {
|
|
3548
|
-
t[verifiedSymbol] = true;
|
|
3549
|
-
return true;
|
|
3550
|
-
};
|
|
3551
|
-
|
|
3552
3558
|
// nip45.ts
|
|
3553
3559
|
var M = 256;
|
|
3554
3560
|
var HLL_HEX_LENGTH = M * 2;
|
|
@@ -3573,7 +3579,7 @@ var NostrTools = (() => {
|
|
|
3573
3579
|
return new Uint8Array(M);
|
|
3574
3580
|
}
|
|
3575
3581
|
function hllDecode(hex2) {
|
|
3576
|
-
if (hex2.length !== HLL_HEX_LENGTH || !/^[0-9a-
|
|
3582
|
+
if (hex2.length !== HLL_HEX_LENGTH || !/^[0-9a-f]+$/.test(hex2))
|
|
3577
3583
|
return void 0;
|
|
3578
3584
|
const registers = new Uint8Array(M);
|
|
3579
3585
|
for (let i2 = 0; i2 < M; i2++) {
|
|
@@ -3614,7 +3620,6 @@ var NostrTools = (() => {
|
|
|
3614
3620
|
enableReconnect;
|
|
3615
3621
|
idleTimeout = 2e4;
|
|
3616
3622
|
automaticallyAuth;
|
|
3617
|
-
trustedRelayURLs = /* @__PURE__ */ new Set();
|
|
3618
3623
|
onRelayConnectionFailure;
|
|
3619
3624
|
onRelayConnectionSuccess;
|
|
3620
3625
|
allowConnectingToRelay;
|
|
@@ -3638,7 +3643,7 @@ var NostrTools = (() => {
|
|
|
3638
3643
|
let relay = this.relays.get(url);
|
|
3639
3644
|
if (!relay) {
|
|
3640
3645
|
relay = new AbstractRelay(url, {
|
|
3641
|
-
verifyEvent: this.
|
|
3646
|
+
verifyEvent: this.verifyEvent,
|
|
3642
3647
|
websocketImplementation: this._WebSocket,
|
|
3643
3648
|
enablePing: this.enablePing,
|
|
3644
3649
|
enableReconnect: this.enableReconnect,
|
|
@@ -3722,11 +3727,11 @@ var NostrTools = (() => {
|
|
|
3722
3727
|
}
|
|
3723
3728
|
};
|
|
3724
3729
|
const closesReceived = [];
|
|
3725
|
-
let handleClose = (i2, reason) => {
|
|
3730
|
+
let handleClose = (i2, url, reason) => {
|
|
3726
3731
|
if (closesReceived[i2])
|
|
3727
3732
|
return;
|
|
3728
3733
|
handleEose(i2);
|
|
3729
|
-
closesReceived[i2] = reason;
|
|
3734
|
+
closesReceived[i2] = { url, reason };
|
|
3730
3735
|
if (closesReceived.filter((a) => a).length === groupedRequests.length) {
|
|
3731
3736
|
params.onclose?.(closesReceived);
|
|
3732
3737
|
handleClose = () => {
|
|
@@ -3744,7 +3749,7 @@ var NostrTools = (() => {
|
|
|
3744
3749
|
const allOpened = Promise.all(
|
|
3745
3750
|
groupedRequests.map(async ({ url, filters }, i2) => {
|
|
3746
3751
|
if (this.allowConnectingToRelay?.(url, ["read", filters]) === false) {
|
|
3747
|
-
handleClose(i2, "connection skipped by allowConnectingToRelay");
|
|
3752
|
+
handleClose(i2, url, "connection skipped by allowConnectingToRelay");
|
|
3748
3753
|
return;
|
|
3749
3754
|
}
|
|
3750
3755
|
let relay;
|
|
@@ -3755,7 +3760,7 @@ var NostrTools = (() => {
|
|
|
3755
3760
|
});
|
|
3756
3761
|
} catch (err) {
|
|
3757
3762
|
this.onRelayConnectionFailure?.(url);
|
|
3758
|
-
handleClose(i2, err?.message || String(err));
|
|
3763
|
+
handleClose(i2, url, err?.message || String(err));
|
|
3759
3764
|
return;
|
|
3760
3765
|
}
|
|
3761
3766
|
this.onRelayConnectionSuccess?.(url);
|
|
@@ -3769,17 +3774,17 @@ var NostrTools = (() => {
|
|
|
3769
3774
|
...params,
|
|
3770
3775
|
oneose: () => handleEose(i2),
|
|
3771
3776
|
onclose: (reason2) => {
|
|
3772
|
-
handleClose(i2, reason2);
|
|
3777
|
+
handleClose(i2, url, reason2);
|
|
3773
3778
|
},
|
|
3774
3779
|
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
|
3775
3780
|
eoseTimeout: params.maxWait,
|
|
3776
3781
|
abort: params.abort
|
|
3777
3782
|
});
|
|
3778
3783
|
}).catch((err) => {
|
|
3779
|
-
handleClose(i2, `auth was required and attempted, but failed with: ${err}`);
|
|
3784
|
+
handleClose(i2, url, `auth was required and attempted, but failed with: ${err}`);
|
|
3780
3785
|
});
|
|
3781
3786
|
} else {
|
|
3782
|
-
handleClose(i2, reason);
|
|
3787
|
+
handleClose(i2, url, reason);
|
|
3783
3788
|
}
|
|
3784
3789
|
},
|
|
3785
3790
|
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
|
@@ -3807,7 +3812,7 @@ var NostrTools = (() => {
|
|
|
3807
3812
|
if (subcloser)
|
|
3808
3813
|
subcloser.close(reason);
|
|
3809
3814
|
else
|
|
3810
|
-
params.onclose?.(relays.map((
|
|
3815
|
+
params.onclose?.(relays.map((url) => ({ url, reason })));
|
|
3811
3816
|
}
|
|
3812
3817
|
});
|
|
3813
3818
|
return subcloser;
|
|
@@ -5223,7 +5228,6 @@ var NostrTools = (() => {
|
|
|
5223
5228
|
__export(nip10_exports, {
|
|
5224
5229
|
parse: () => parse
|
|
5225
5230
|
});
|
|
5226
|
-
var HEX64 = /^[0-9a-fA-F]{64}$/;
|
|
5227
5231
|
function parse(event) {
|
|
5228
5232
|
const result = {
|
|
5229
5233
|
reply: void 0,
|
|
@@ -5236,12 +5240,12 @@ var NostrTools = (() => {
|
|
|
5236
5240
|
let maybeRoot;
|
|
5237
5241
|
for (let i2 = event.tags.length - 1; i2 >= 0; i2--) {
|
|
5238
5242
|
const tag = event.tags[i2];
|
|
5239
|
-
if (tag[0] === "e" && tag[1] &&
|
|
5243
|
+
if (tag[0] === "e" && tag[1] && isHex32(tag[1])) {
|
|
5240
5244
|
const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag;
|
|
5241
5245
|
const eventPointer = {
|
|
5242
5246
|
id: eTagEventId,
|
|
5243
5247
|
relays: eTagRelayUrl ? [eTagRelayUrl] : [],
|
|
5244
|
-
author: eTagAuthor &&
|
|
5248
|
+
author: eTagAuthor && isHex32(eTagAuthor) ? eTagAuthor : void 0
|
|
5245
5249
|
};
|
|
5246
5250
|
if (eTagMarker === "root") {
|
|
5247
5251
|
result.root = eventPointer;
|
|
@@ -5263,14 +5267,14 @@ var NostrTools = (() => {
|
|
|
5263
5267
|
result.mentions.push(eventPointer);
|
|
5264
5268
|
continue;
|
|
5265
5269
|
}
|
|
5266
|
-
if (tag[0] === "q" && tag[1] &&
|
|
5270
|
+
if (tag[0] === "q" && tag[1] && isHex32(tag[1])) {
|
|
5267
5271
|
const [_, eTagEventId, eTagRelayUrl] = tag;
|
|
5268
5272
|
result.quotes.push({
|
|
5269
5273
|
id: eTagEventId,
|
|
5270
5274
|
relays: eTagRelayUrl ? [eTagRelayUrl] : []
|
|
5271
5275
|
});
|
|
5272
5276
|
}
|
|
5273
|
-
if (tag[0] === "p" && tag[1] &&
|
|
5277
|
+
if (tag[0] === "p" && tag[1] && isHex32(tag[1])) {
|
|
5274
5278
|
result.profiles.push({
|
|
5275
5279
|
pubkey: tag[1],
|
|
5276
5280
|
relays: tag[2] ? [tag[2]] : []
|
|
@@ -6390,7 +6394,6 @@ var NostrTools = (() => {
|
|
|
6390
6394
|
__export(nip22_exports, {
|
|
6391
6395
|
parse: () => parse3
|
|
6392
6396
|
});
|
|
6393
|
-
var HEX642 = /^[0-9a-fA-F]{64}$/;
|
|
6394
6397
|
function parseKind(kind) {
|
|
6395
6398
|
if (!kind)
|
|
6396
6399
|
return void 0;
|
|
@@ -6405,7 +6408,7 @@ var NostrTools = (() => {
|
|
|
6405
6408
|
if (Number.isNaN(kind))
|
|
6406
6409
|
return void 0;
|
|
6407
6410
|
const pubkey = value.slice(idx + 1, idx2);
|
|
6408
|
-
if (!
|
|
6411
|
+
if (!isHex32(pubkey))
|
|
6409
6412
|
return void 0;
|
|
6410
6413
|
return {
|
|
6411
6414
|
kind,
|
|
@@ -6418,12 +6421,12 @@ var NostrTools = (() => {
|
|
|
6418
6421
|
switch (tag[0]) {
|
|
6419
6422
|
case "E":
|
|
6420
6423
|
case "e":
|
|
6421
|
-
if (!tag[1] || !
|
|
6424
|
+
if (!tag[1] || !isHex32(tag[1]))
|
|
6422
6425
|
return void 0;
|
|
6423
6426
|
return {
|
|
6424
6427
|
id: tag[1],
|
|
6425
6428
|
relays: tag[2] ? [tag[2]] : [],
|
|
6426
|
-
author: tag[3] &&
|
|
6429
|
+
author: tag[3] && isHex32(tag[3]) ? tag[3] : void 0
|
|
6427
6430
|
};
|
|
6428
6431
|
case "A":
|
|
6429
6432
|
case "a":
|
|
@@ -6446,12 +6449,12 @@ var NostrTools = (() => {
|
|
|
6446
6449
|
if (tag[1].includes(":")) {
|
|
6447
6450
|
return parseAddressPointer(tag[1], tag[2]);
|
|
6448
6451
|
}
|
|
6449
|
-
if (!
|
|
6452
|
+
if (!isHex32(tag[1]))
|
|
6450
6453
|
return void 0;
|
|
6451
6454
|
return {
|
|
6452
6455
|
id: tag[1],
|
|
6453
6456
|
relays: tag[2] ? [tag[2]] : [],
|
|
6454
|
-
author: tag[3] &&
|
|
6457
|
+
author: tag[3] && isHex32(tag[3]) ? tag[3] : void 0
|
|
6455
6458
|
};
|
|
6456
6459
|
}
|
|
6457
6460
|
function choosePointer(candidates) {
|
|
@@ -6511,7 +6514,7 @@ var NostrTools = (() => {
|
|
|
6511
6514
|
result.quotes.push(pointer);
|
|
6512
6515
|
continue;
|
|
6513
6516
|
}
|
|
6514
|
-
if ((tag[0] === "P" || tag[0] === "p") && tag[1] &&
|
|
6517
|
+
if ((tag[0] === "P" || tag[0] === "p") && tag[1] && isHex32(tag[1])) {
|
|
6515
6518
|
result.profiles.push({
|
|
6516
6519
|
pubkey: tag[1],
|
|
6517
6520
|
relays: tag[2] ? [tag[2]] : []
|
|
@@ -7011,10 +7014,10 @@ var NostrTools = (() => {
|
|
|
7011
7014
|
let p = zapRequest.tags.find(([t, v]) => t === "p" && v);
|
|
7012
7015
|
if (!p)
|
|
7013
7016
|
return "Zap request doesn't have a 'p' tag.";
|
|
7014
|
-
if (!p[1]
|
|
7017
|
+
if (!isHex32(p[1]))
|
|
7015
7018
|
return "Zap request 'p' tag is not valid hex.";
|
|
7016
7019
|
let e = zapRequest.tags.find(([t, v]) => t === "e" && v);
|
|
7017
|
-
if (e && !e[1]
|
|
7020
|
+
if (e && !isHex32(e[1]))
|
|
7018
7021
|
return "Zap request 'e' tag is not valid hex.";
|
|
7019
7022
|
let relays = zapRequest.tags.find(([t, v]) => t === "relays" && v);
|
|
7020
7023
|
if (!relays)
|