"use strict"; var NostrTools = (() => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); // index.ts var nostr_tools_exports = {}; __export(nostr_tools_exports, { Relay: () => Relay, SimplePool: () => SimplePool, finalizeEvent: () => finalizeEvent, fj: () => fakejson_exports, generateSecretKey: () => generateSecretKey, getEventHash: () => getEventHash, getFilterLimit: () => getFilterLimit, getPublicKey: () => getPublicKey, kinds: () => kinds_exports, matchFilter: () => matchFilter, matchFilters: () => matchFilters, mergeFilters: () => mergeFilters, nip04: () => nip04_exports, nip05: () => nip05_exports, nip10: () => nip10_exports, nip11: () => nip11_exports, nip13: () => nip13_exports, nip17: () => nip17_exports, nip18: () => nip18_exports, nip19: () => nip19_exports, nip21: () => nip21_exports, nip25: () => nip25_exports, nip27: () => nip27_exports, nip28: () => nip28_exports, nip30: () => nip30_exports, nip39: () => nip39_exports, nip42: () => nip42_exports, nip44: () => nip44_exports, nip47: () => nip47_exports, nip54: () => nip54_exports, nip57: () => nip57_exports, nip59: () => nip59_exports, nip77: () => nip77_exports, nip98: () => nip98_exports, parseReferences: () => parseReferences, serializeEvent: () => serializeEvent, sortEvents: () => sortEvents, utils: () => utils_exports, validateEvent: () => validateEvent, verifiedSymbol: () => verifiedSymbol, verifyEvent: () => verifyEvent }); // node_modules/@noble/hashes/utils.js function isBytes(a) { return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array"; } function anumber(n, title = "") { if (!Number.isSafeInteger(n) || n < 0) { const prefix = title && `"${title}" `; throw new Error(`${prefix}expected integer >= 0, got ${n}`); } } function abytes(value, length, title = "") { const bytes = isBytes(value); const len = value?.length; const needsLen = length !== void 0; if (!bytes || needsLen && len !== length) { const prefix = title && `"${title}" `; const ofLen = needsLen ? ` of length ${length}` : ""; const got = bytes ? `length=${len}` : `type=${typeof value}`; throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got); } return value; } function ahash(h) { if (typeof h !== "function" || typeof h.create !== "function") throw new Error("Hash must wrapped by utils.createHasher"); anumber(h.outputLen); anumber(h.blockLen); } function aexists(instance, checkFinished = true) { if (instance.destroyed) throw new Error("Hash instance has been destroyed"); if (checkFinished && instance.finished) throw new Error("Hash#digest() has already been called"); } function aoutput(out, instance) { abytes(out, void 0, "digestInto() output"); const min = instance.outputLen; if (out.length < min) { throw new Error('"digestInto() output" expected to be of length >=' + min); } } function clean(...arrays) { for (let i2 = 0; i2 < arrays.length; i2++) { arrays[i2].fill(0); } } function createView(arr) { return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); } function rotr(word, shift) { return word << 32 - shift | word >>> shift; } var hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")(); var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i2) => i2.toString(16).padStart(2, "0")); function bytesToHex(bytes) { abytes(bytes); if (hasHexBuiltin) return bytes.toHex(); let hex2 = ""; for (let i2 = 0; i2 < bytes.length; i2++) { hex2 += hexes[bytes[i2]]; } return hex2; } var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; function asciiToBase16(ch) { if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); return; } function hexToBytes(hex2) { if (typeof hex2 !== "string") throw new Error("hex string expected, got " + typeof hex2); if (hasHexBuiltin) return Uint8Array.fromHex(hex2); const hl = hex2.length; const al = hl / 2; if (hl % 2) throw new Error("hex string expected, got unpadded hex of length " + hl); const array = new Uint8Array(al); for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { const n1 = asciiToBase16(hex2.charCodeAt(hi)); const n2 = asciiToBase16(hex2.charCodeAt(hi + 1)); if (n1 === void 0 || n2 === void 0) { const char = hex2[hi] + hex2[hi + 1]; throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi); } array[ai] = n1 * 16 + n2; } return array; } function concatBytes(...arrays) { let sum = 0; for (let i2 = 0; i2 < arrays.length; i2++) { const a = arrays[i2]; abytes(a); sum += a.length; } const res = new Uint8Array(sum); for (let i2 = 0, pad2 = 0; i2 < arrays.length; i2++) { const a = arrays[i2]; res.set(a, pad2); pad2 += a.length; } return res; } function createHasher(hashCons, info = {}) { const hashC = (msg, opts) => hashCons(opts).update(msg).digest(); const tmp = hashCons(void 0); hashC.outputLen = tmp.outputLen; hashC.blockLen = tmp.blockLen; hashC.create = (opts) => hashCons(opts); Object.assign(hashC, info); return Object.freeze(hashC); } function randomBytes(bytesLength = 32) { const cr = typeof globalThis === "object" ? globalThis.crypto : null; if (typeof cr?.getRandomValues !== "function") throw new Error("crypto.getRandomValues must be defined"); return cr.getRandomValues(new Uint8Array(bytesLength)); } var oidNist = (suffix) => ({ oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix]) }); // node_modules/@noble/hashes/_md.js function Chi(a, b, c) { return a & b ^ ~a & c; } function Maj(a, b, c) { return a & b ^ a & c ^ b & c; } var HashMD = class { blockLen; outputLen; padOffset; isLE; buffer; view; finished = false; length = 0; pos = 0; destroyed = false; constructor(blockLen, outputLen, padOffset, isLE2) { this.blockLen = blockLen; this.outputLen = outputLen; this.padOffset = padOffset; this.isLE = isLE2; this.buffer = new Uint8Array(blockLen); this.view = createView(this.buffer); } update(data) { aexists(this); abytes(data); const { view, buffer, blockLen } = this; const len = data.length; for (let pos = 0; pos < len; ) { const take = Math.min(blockLen - this.pos, len - pos); if (take === blockLen) { const dataView = createView(data); for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos); continue; } buffer.set(data.subarray(pos, pos + take), this.pos); this.pos += take; pos += take; if (this.pos === blockLen) { this.process(view, 0); this.pos = 0; } } this.length += data.length; this.roundClean(); return this; } digestInto(out) { aexists(this); aoutput(out, this); this.finished = true; const { buffer, view, blockLen, isLE: isLE2 } = this; let { pos } = this; buffer[pos++] = 128; clean(this.buffer.subarray(pos)); if (this.padOffset > blockLen - pos) { this.process(view, 0); pos = 0; } for (let i2 = pos; i2 < blockLen; i2++) buffer[i2] = 0; view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE2); this.process(view, 0); const oview = createView(out); const len = this.outputLen; if (len % 4) throw new Error("_sha2: outputLen must be aligned to 32bit"); const outLen = len / 4; const state = this.get(); if (outLen > state.length) throw new Error("_sha2: outputLen bigger than state"); for (let i2 = 0; i2 < outLen; i2++) oview.setUint32(4 * i2, state[i2], isLE2); } digest() { const { buffer, outputLen } = this; this.digestInto(buffer); const res = buffer.slice(0, outputLen); this.destroy(); return res; } _cloneInto(to) { to ||= new this.constructor(); to.set(...this.get()); const { blockLen, buffer, length, finished, destroyed, pos } = this; to.destroyed = destroyed; to.finished = finished; to.length = length; to.pos = pos; if (length % blockLen) to.buffer.set(buffer); return to; } clone() { return this._cloneInto(); } }; var SHA256_IV = /* @__PURE__ */ Uint32Array.from([ 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225 ]); // node_modules/@noble/hashes/sha2.js var SHA256_K = /* @__PURE__ */ Uint32Array.from([ 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 ]); var SHA256_W = /* @__PURE__ */ new Uint32Array(64); var SHA2_32B = class extends HashMD { constructor(outputLen) { super(64, outputLen, 8, false); } get() { const { A, B, C, D, E, F, G, H } = this; return [A, B, C, D, E, F, G, H]; } set(A, B, C, D, E, F, G, H) { this.A = A | 0; this.B = B | 0; this.C = C | 0; this.D = D | 0; this.E = E | 0; this.F = F | 0; this.G = G | 0; this.H = H | 0; } process(view, offset) { for (let i2 = 0; i2 < 16; i2++, offset += 4) SHA256_W[i2] = view.getUint32(offset, false); for (let i2 = 16; i2 < 64; i2++) { const W15 = SHA256_W[i2 - 15]; const W2 = SHA256_W[i2 - 2]; const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3; const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10; SHA256_W[i2] = s1 + SHA256_W[i2 - 7] + s0 + SHA256_W[i2 - 16] | 0; } let { A, B, C, D, E, F, G, H } = this; for (let i2 = 0; i2 < 64; i2++) { const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i2] + SHA256_W[i2] | 0; const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); const T2 = sigma0 + Maj(A, B, C) | 0; H = G; G = F; F = E; E = D + T1 | 0; D = C; C = B; B = A; A = T1 + T2 | 0; } A = A + this.A | 0; B = B + this.B | 0; C = C + this.C | 0; D = D + this.D | 0; E = E + this.E | 0; F = F + this.F | 0; G = G + this.G | 0; H = H + this.H | 0; this.set(A, B, C, D, E, F, G, H); } roundClean() { clean(SHA256_W); } destroy() { this.set(0, 0, 0, 0, 0, 0, 0, 0); clean(this.buffer); } }; var _SHA256 = class extends SHA2_32B { A = SHA256_IV[0] | 0; B = SHA256_IV[1] | 0; C = SHA256_IV[2] | 0; D = SHA256_IV[3] | 0; E = SHA256_IV[4] | 0; F = SHA256_IV[5] | 0; G = SHA256_IV[6] | 0; H = SHA256_IV[7] | 0; constructor() { super(32); } }; var sha256 = /* @__PURE__ */ createHasher( () => new _SHA256(), /* @__PURE__ */ oidNist(1) ); // node_modules/@noble/curves/utils.js var _0n = /* @__PURE__ */ BigInt(0); var _1n = /* @__PURE__ */ BigInt(1); function abool(value, title = "") { if (typeof value !== "boolean") { const prefix = title && `"${title}" `; throw new Error(prefix + "expected boolean, got type=" + typeof value); } return value; } function abignumber(n) { if (typeof n === "bigint") { if (!isPosBig(n)) throw new Error("positive bigint expected, got " + n); } else anumber(n); return n; } function numberToHexUnpadded(num2) { const hex2 = abignumber(num2).toString(16); return hex2.length & 1 ? "0" + hex2 : hex2; } function hexToNumber(hex2) { if (typeof hex2 !== "string") throw new Error("hex string expected, got " + typeof hex2); return hex2 === "" ? _0n : BigInt("0x" + hex2); } function bytesToNumberBE(bytes) { return hexToNumber(bytesToHex(bytes)); } function bytesToNumberLE(bytes) { return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse())); } function numberToBytesBE(n, len) { anumber(len); n = abignumber(n); const res = hexToBytes(n.toString(16).padStart(len * 2, "0")); if (res.length !== len) throw new Error("number too large"); return res; } function numberToBytesLE(n, len) { return numberToBytesBE(n, len).reverse(); } function copyBytes(bytes) { return Uint8Array.from(bytes); } function asciiToBytes(ascii) { return Uint8Array.from(ascii, (c, i2) => { const charCode = c.charCodeAt(0); if (c.length !== 1 || charCode > 127) { throw new Error(`string contains non-ASCII character "${ascii[i2]}" with code ${charCode} at position ${i2}`); } return charCode; }); } var isPosBig = (n) => typeof n === "bigint" && _0n <= n; function inRange(n, min, max) { return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max; } function aInRange(title, n, min, max) { if (!inRange(n, min, max)) throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n); } function bitLen(n) { let len; for (len = 0; n > _0n; n >>= _1n, len += 1) ; return len; } var bitMask = (n) => (_1n << BigInt(n)) - _1n; function createHmacDrbg(hashLen, qByteLen, hmacFn) { anumber(hashLen, "hashLen"); anumber(qByteLen, "qByteLen"); if (typeof hmacFn !== "function") throw new Error("hmacFn must be a function"); const u8n = (len) => new Uint8Array(len); const NULL = Uint8Array.of(); const byte0 = Uint8Array.of(0); const byte1 = Uint8Array.of(1); const _maxDrbgIters = 1e3; let v = u8n(hashLen); let k = u8n(hashLen); let i2 = 0; const reset = () => { v.fill(1); k.fill(0); i2 = 0; }; const h = (...msgs) => hmacFn(k, concatBytes(v, ...msgs)); const reseed = (seed = NULL) => { k = h(byte0, seed); v = h(); if (seed.length === 0) return; k = h(byte1, seed); v = h(); }; const gen = () => { if (i2++ >= _maxDrbgIters) throw new Error("drbg: tried max amount of iterations"); let len = 0; const out = []; while (len < qByteLen) { v = h(); const sl = v.slice(); out.push(sl); len += v.length; } return concatBytes(...out); }; const genUntil = (seed, pred) => { reset(); reseed(seed); let res = void 0; while (!(res = pred(gen()))) reseed(); reset(); return res; }; return genUntil; } function validateObject(object, fields = {}, optFields = {}) { if (!object || typeof object !== "object") throw new Error("expected valid options object"); function checkField(fieldName, expectedType, isOpt) { const val = object[fieldName]; if (isOpt && val === void 0) return; const current = typeof val; if (current !== expectedType || val === null) throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`); } const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt)); iter(fields, false); iter(optFields, true); } function memoized(fn) { const map = /* @__PURE__ */ new WeakMap(); return (arg, ...args) => { const val = map.get(arg); if (val !== void 0) return val; const computed = fn(arg, ...args); map.set(arg, computed); return computed; }; } // node_modules/@noble/curves/abstract/modular.js var _0n2 = /* @__PURE__ */ BigInt(0); var _1n2 = /* @__PURE__ */ BigInt(1); var _2n = /* @__PURE__ */ BigInt(2); var _3n = /* @__PURE__ */ BigInt(3); var _4n = /* @__PURE__ */ BigInt(4); var _5n = /* @__PURE__ */ BigInt(5); var _7n = /* @__PURE__ */ BigInt(7); var _8n = /* @__PURE__ */ BigInt(8); var _9n = /* @__PURE__ */ BigInt(9); var _16n = /* @__PURE__ */ BigInt(16); function mod(a, b) { const result = a % b; return result >= _0n2 ? result : b + result; } function pow2(x, power, modulo) { let res = x; while (power-- > _0n2) { res *= res; res %= modulo; } return res; } function invert(number, modulo) { if (number === _0n2) throw new Error("invert: expected non-zero number"); if (modulo <= _0n2) throw new Error("invert: expected positive modulus, got " + modulo); let a = mod(number, modulo); let b = modulo; let x = _0n2, y = _1n2, u = _1n2, v = _0n2; while (a !== _0n2) { const q = b / a; const r = b % a; const m = x - u * q; const n = y - v * q; b = a, a = r, x = u, y = v, u = m, v = n; } const gcd2 = b; if (gcd2 !== _1n2) throw new Error("invert: does not exist"); return mod(x, modulo); } function assertIsSquare(Fp, root, n) { if (!Fp.eql(Fp.sqr(root), n)) throw new Error("Cannot find square root"); } function sqrt3mod4(Fp, n) { const p1div4 = (Fp.ORDER + _1n2) / _4n; const root = Fp.pow(n, p1div4); assertIsSquare(Fp, root, n); return root; } function sqrt5mod8(Fp, n) { const p5div8 = (Fp.ORDER - _5n) / _8n; const n2 = Fp.mul(n, _2n); const v = Fp.pow(n2, p5div8); const nv = Fp.mul(n, v); const i2 = Fp.mul(Fp.mul(nv, _2n), v); const root = Fp.mul(nv, Fp.sub(i2, Fp.ONE)); assertIsSquare(Fp, root, n); return root; } function sqrt9mod16(P) { const Fp_ = Field(P); const tn = tonelliShanks(P); const c1 = tn(Fp_, Fp_.neg(Fp_.ONE)); const c2 = tn(Fp_, c1); const c3 = tn(Fp_, Fp_.neg(c1)); const c4 = (P + _7n) / _16n; return (Fp, n) => { let tv1 = Fp.pow(n, c4); let tv2 = Fp.mul(tv1, c1); const tv3 = Fp.mul(tv1, c2); const tv4 = Fp.mul(tv1, c3); const e1 = Fp.eql(Fp.sqr(tv2), n); const e2 = Fp.eql(Fp.sqr(tv3), n); tv1 = Fp.cmov(tv1, tv2, e1); tv2 = Fp.cmov(tv4, tv3, e2); const e3 = Fp.eql(Fp.sqr(tv2), n); const root = Fp.cmov(tv1, tv2, e3); assertIsSquare(Fp, root, n); return root; }; } function tonelliShanks(P) { if (P < _3n) throw new Error("sqrt is not defined for small field"); let Q = P - _1n2; let S = 0; while (Q % _2n === _0n2) { Q /= _2n; S++; } let Z = _2n; const _Fp = Field(P); while (FpLegendre(_Fp, Z) === 1) { if (Z++ > 1e3) throw new Error("Cannot find square root: probably non-prime P"); } if (S === 1) return sqrt3mod4; let cc = _Fp.pow(Z, Q); const Q1div2 = (Q + _1n2) / _2n; return function tonelliSlow(Fp, n) { if (Fp.is0(n)) return n; if (FpLegendre(Fp, n) !== 1) throw new Error("Cannot find square root"); let M = S; let c = Fp.mul(Fp.ONE, cc); let t = Fp.pow(n, Q); let R = Fp.pow(n, Q1div2); while (!Fp.eql(t, Fp.ONE)) { if (Fp.is0(t)) return Fp.ZERO; let i2 = 1; let t_tmp = Fp.sqr(t); while (!Fp.eql(t_tmp, Fp.ONE)) { i2++; t_tmp = Fp.sqr(t_tmp); if (i2 === M) throw new Error("Cannot find square root"); } const exponent = _1n2 << BigInt(M - i2 - 1); const b = Fp.pow(c, exponent); M = i2; c = Fp.sqr(b); t = Fp.mul(t, c); R = Fp.mul(R, b); } return R; }; } function FpSqrt(P) { if (P % _4n === _3n) return sqrt3mod4; if (P % _8n === _5n) return sqrt5mod8; if (P % _16n === _9n) return sqrt9mod16(P); return tonelliShanks(P); } var FIELD_FIELDS = [ "create", "isValid", "is0", "neg", "inv", "sqrt", "sqr", "eql", "add", "sub", "mul", "pow", "div", "addN", "subN", "mulN", "sqrN" ]; function validateField(field) { const initial = { ORDER: "bigint", BYTES: "number", BITS: "number" }; const opts = FIELD_FIELDS.reduce((map, val) => { map[val] = "function"; return map; }, initial); validateObject(field, opts); return field; } function FpPow(Fp, num2, power) { if (power < _0n2) throw new Error("invalid exponent, negatives unsupported"); if (power === _0n2) return Fp.ONE; if (power === _1n2) return num2; let p = Fp.ONE; let d = num2; while (power > _0n2) { if (power & _1n2) p = Fp.mul(p, d); d = Fp.sqr(d); power >>= _1n2; } return p; } function FpInvertBatch(Fp, nums, passZero = false) { const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : void 0); const multipliedAcc = nums.reduce((acc, num2, i2) => { if (Fp.is0(num2)) return acc; inverted[i2] = acc; return Fp.mul(acc, num2); }, Fp.ONE); const invertedAcc = Fp.inv(multipliedAcc); nums.reduceRight((acc, num2, i2) => { if (Fp.is0(num2)) return acc; inverted[i2] = Fp.mul(acc, inverted[i2]); return Fp.mul(acc, num2); }, invertedAcc); return inverted; } function FpLegendre(Fp, n) { const p1mod2 = (Fp.ORDER - _1n2) / _2n; const powered = Fp.pow(n, p1mod2); const yes = Fp.eql(powered, Fp.ONE); const zero = Fp.eql(powered, Fp.ZERO); const no = Fp.eql(powered, Fp.neg(Fp.ONE)); if (!yes && !zero && !no) throw new Error("invalid Legendre symbol result"); return yes ? 1 : zero ? 0 : -1; } function nLength(n, nBitLength) { if (nBitLength !== void 0) anumber(nBitLength); const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length; const nByteLength = Math.ceil(_nBitLength / 8); return { nBitLength: _nBitLength, nByteLength }; } var _Field = class { ORDER; BITS; BYTES; isLE; ZERO = _0n2; ONE = _1n2; _lengths; _sqrt; _mod; constructor(ORDER, opts = {}) { if (ORDER <= _0n2) throw new Error("invalid field: expected ORDER > 0, got " + ORDER); let _nbitLength = void 0; this.isLE = false; if (opts != null && typeof opts === "object") { if (typeof opts.BITS === "number") _nbitLength = opts.BITS; if (typeof opts.sqrt === "function") this.sqrt = opts.sqrt; if (typeof opts.isLE === "boolean") this.isLE = opts.isLE; if (opts.allowedLengths) this._lengths = opts.allowedLengths?.slice(); if (typeof opts.modFromBytes === "boolean") this._mod = opts.modFromBytes; } const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength); if (nByteLength > 2048) throw new Error("invalid field: expected ORDER of <= 2048 bytes"); this.ORDER = ORDER; this.BITS = nBitLength; this.BYTES = nByteLength; this._sqrt = void 0; Object.preventExtensions(this); } create(num2) { return mod(num2, this.ORDER); } isValid(num2) { if (typeof num2 !== "bigint") throw new Error("invalid field element: expected bigint, got " + typeof num2); return _0n2 <= num2 && num2 < this.ORDER; } is0(num2) { return num2 === _0n2; } isValidNot0(num2) { return !this.is0(num2) && this.isValid(num2); } isOdd(num2) { return (num2 & _1n2) === _1n2; } neg(num2) { return mod(-num2, this.ORDER); } eql(lhs, rhs) { return lhs === rhs; } sqr(num2) { return mod(num2 * num2, this.ORDER); } add(lhs, rhs) { return mod(lhs + rhs, this.ORDER); } sub(lhs, rhs) { return mod(lhs - rhs, this.ORDER); } mul(lhs, rhs) { return mod(lhs * rhs, this.ORDER); } pow(num2, power) { return FpPow(this, num2, power); } div(lhs, rhs) { return mod(lhs * invert(rhs, this.ORDER), this.ORDER); } sqrN(num2) { return num2 * num2; } addN(lhs, rhs) { return lhs + rhs; } subN(lhs, rhs) { return lhs - rhs; } mulN(lhs, rhs) { return lhs * rhs; } inv(num2) { return invert(num2, this.ORDER); } sqrt(num2) { if (!this._sqrt) this._sqrt = FpSqrt(this.ORDER); return this._sqrt(this, num2); } toBytes(num2) { return this.isLE ? numberToBytesLE(num2, this.BYTES) : numberToBytesBE(num2, this.BYTES); } fromBytes(bytes, skipValidation = false) { abytes(bytes); const { _lengths: allowedLengths, BYTES, isLE: isLE2, ORDER, _mod: modFromBytes } = this; if (allowedLengths) { if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) { throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length); } const padded = new Uint8Array(BYTES); padded.set(bytes, isLE2 ? 0 : padded.length - bytes.length); bytes = padded; } if (bytes.length !== BYTES) throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length); let scalar = isLE2 ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes); if (modFromBytes) scalar = mod(scalar, ORDER); if (!skipValidation) { if (!this.isValid(scalar)) throw new Error("invalid field element: outside of range 0..ORDER"); } return scalar; } invertBatch(lst) { return FpInvertBatch(this, lst); } cmov(a, b, condition) { return condition ? b : a; } }; function Field(ORDER, opts = {}) { return new _Field(ORDER, opts); } function getFieldBytesLength(fieldOrder) { if (typeof fieldOrder !== "bigint") throw new Error("field order must be bigint"); const bitLength = fieldOrder.toString(2).length; return Math.ceil(bitLength / 8); } function getMinHashLength(fieldOrder) { const length = getFieldBytesLength(fieldOrder); return length + Math.ceil(length / 2); } function mapHashToField(key, fieldOrder, isLE2 = false) { abytes(key); const len = key.length; const fieldLen = getFieldBytesLength(fieldOrder); const minLen = getMinHashLength(fieldOrder); if (len < 16 || len < minLen || len > 1024) throw new Error("expected " + minLen + "-1024 bytes of input, got " + len); const num2 = isLE2 ? bytesToNumberLE(key) : bytesToNumberBE(key); const reduced = mod(num2, fieldOrder - _1n2) + _1n2; return isLE2 ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen); } // node_modules/@noble/curves/abstract/curve.js var _0n3 = /* @__PURE__ */ BigInt(0); var _1n3 = /* @__PURE__ */ BigInt(1); function negateCt(condition, item) { const neg = item.negate(); return condition ? neg : item; } function normalizeZ(c, points) { const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z)); return points.map((p, i2) => c.fromAffine(p.toAffine(invertedZs[i2]))); } function validateW(W, bits) { if (!Number.isSafeInteger(W) || W <= 0 || W > bits) throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W); } function calcWOpts(W, scalarBits) { validateW(W, scalarBits); const windows = Math.ceil(scalarBits / W) + 1; const windowSize = 2 ** (W - 1); const maxNumber = 2 ** W; const mask = bitMask(W); const shiftBy = BigInt(W); return { windows, windowSize, mask, maxNumber, shiftBy }; } function calcOffsets(n, window2, wOpts) { const { windowSize, mask, maxNumber, shiftBy } = wOpts; let wbits = Number(n & mask); let nextN = n >> shiftBy; if (wbits > windowSize) { wbits -= maxNumber; nextN += _1n3; } const offsetStart = window2 * windowSize; const offset = offsetStart + Math.abs(wbits) - 1; const isZero = wbits === 0; const isNeg = wbits < 0; const isNegF = window2 % 2 !== 0; const offsetF = offsetStart; return { nextN, offset, isZero, isNeg, isNegF, offsetF }; } var pointPrecomputes = /* @__PURE__ */ new WeakMap(); var pointWindowSizes = /* @__PURE__ */ new WeakMap(); function getW(P) { return pointWindowSizes.get(P) || 1; } function assert0(n) { if (n !== _0n3) throw new Error("invalid wNAF"); } var wNAF = class { BASE; ZERO; Fn; bits; constructor(Point, bits) { this.BASE = Point.BASE; this.ZERO = Point.ZERO; this.Fn = Point.Fn; this.bits = bits; } _unsafeLadder(elm, n, p = this.ZERO) { let d = elm; while (n > _0n3) { if (n & _1n3) p = p.add(d); d = d.double(); n >>= _1n3; } return p; } precomputeWindow(point, W) { const { windows, windowSize } = calcWOpts(W, this.bits); const points = []; let p = point; let base = p; for (let window2 = 0; window2 < windows; window2++) { base = p; points.push(base); for (let i2 = 1; i2 < windowSize; i2++) { base = base.add(p); points.push(base); } p = base.double(); } return points; } wNAF(W, precomputes, n) { if (!this.Fn.isValid(n)) throw new Error("invalid scalar"); let p = this.ZERO; let f = this.BASE; const wo = calcWOpts(W, this.bits); for (let window2 = 0; window2 < wo.windows; window2++) { const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window2, wo); n = nextN; if (isZero) { f = f.add(negateCt(isNegF, precomputes[offsetF])); } else { p = p.add(negateCt(isNeg, precomputes[offset])); } } assert0(n); return { p, f }; } wNAFUnsafe(W, precomputes, n, acc = this.ZERO) { const wo = calcWOpts(W, this.bits); for (let window2 = 0; window2 < wo.windows; window2++) { if (n === _0n3) break; const { nextN, offset, isZero, isNeg } = calcOffsets(n, window2, wo); n = nextN; if (isZero) { continue; } else { const item = precomputes[offset]; acc = acc.add(isNeg ? item.negate() : item); } } assert0(n); return acc; } getPrecomputes(W, point, transform) { let comp = pointPrecomputes.get(point); if (!comp) { comp = this.precomputeWindow(point, W); if (W !== 1) { if (typeof transform === "function") comp = transform(comp); pointPrecomputes.set(point, comp); } } return comp; } cached(point, scalar, transform) { const W = getW(point); return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar); } unsafe(point, scalar, transform, prev) { const W = getW(point); if (W === 1) return this._unsafeLadder(point, scalar, prev); return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev); } createCache(P, W) { validateW(W, this.bits); pointWindowSizes.set(P, W); pointPrecomputes.delete(P); } hasCache(elm) { return getW(elm) !== 1; } }; function mulEndoUnsafe(Point, point, k1, k2) { let acc = point; let p1 = Point.ZERO; let p2 = Point.ZERO; while (k1 > _0n3 || k2 > _0n3) { if (k1 & _1n3) p1 = p1.add(acc); if (k2 & _1n3) p2 = p2.add(acc); acc = acc.double(); k1 >>= _1n3; k2 >>= _1n3; } return { p1, p2 }; } function createField(order, field, isLE2) { if (field) { if (field.ORDER !== order) throw new Error("Field.ORDER must match order: Fp == p, Fn == n"); validateField(field); return field; } else { return Field(order, { isLE: isLE2 }); } } function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) { if (FpFnLE === void 0) FpFnLE = type === "edwards"; if (!CURVE || typeof CURVE !== "object") throw new Error(`expected valid ${type} CURVE object`); for (const p of ["p", "n", "h"]) { const val = CURVE[p]; if (!(typeof val === "bigint" && val > _0n3)) throw new Error(`CURVE.${p} must be positive bigint`); } const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE); const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE); const _b = type === "weierstrass" ? "b" : "d"; const params = ["Gx", "Gy", "a", _b]; for (const p of params) { if (!Fp.isValid(CURVE[p])) throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`); } CURVE = Object.freeze(Object.assign({}, CURVE)); return { CURVE, Fp, Fn }; } function createKeygen(randomSecretKey, getPublicKey2) { return function keygen(seed) { const secretKey = randomSecretKey(seed); return { secretKey, publicKey: getPublicKey2(secretKey) }; }; } // node_modules/@noble/hashes/hmac.js var _HMAC = class { oHash; iHash; blockLen; outputLen; finished = false; destroyed = false; constructor(hash, key) { ahash(hash); abytes(key, void 0, "key"); this.iHash = hash.create(); if (typeof this.iHash.update !== "function") throw new Error("Expected instance of class which extends utils.Hash"); this.blockLen = this.iHash.blockLen; this.outputLen = this.iHash.outputLen; const blockLen = this.blockLen; const pad2 = new Uint8Array(blockLen); pad2.set(key.length > blockLen ? hash.create().update(key).digest() : key); for (let i2 = 0; i2 < pad2.length; i2++) pad2[i2] ^= 54; this.iHash.update(pad2); this.oHash = hash.create(); for (let i2 = 0; i2 < pad2.length; i2++) pad2[i2] ^= 54 ^ 92; this.oHash.update(pad2); clean(pad2); } update(buf) { aexists(this); this.iHash.update(buf); return this; } digestInto(out) { aexists(this); abytes(out, this.outputLen, "output"); this.finished = true; this.iHash.digestInto(out); this.oHash.update(out); this.oHash.digestInto(out); this.destroy(); } digest() { const out = new Uint8Array(this.oHash.outputLen); this.digestInto(out); return out; } _cloneInto(to) { to ||= Object.create(Object.getPrototypeOf(this), {}); const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; to = to; to.finished = finished; to.destroyed = destroyed; to.blockLen = blockLen; to.outputLen = outputLen; to.oHash = oHash._cloneInto(to.oHash); to.iHash = iHash._cloneInto(to.iHash); return to; } clone() { return this._cloneInto(); } destroy() { this.destroyed = true; this.oHash.destroy(); this.iHash.destroy(); } }; var hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest(); hmac.create = (hash, key) => new _HMAC(hash, key); // node_modules/@noble/curves/abstract/weierstrass.js var divNearest = (num2, den) => (num2 + (num2 >= 0 ? den : -den) / _2n2) / den; function _splitEndoScalar(k, basis, n) { const [[a1, b1], [a2, b2]] = basis; const c1 = divNearest(b2 * k, n); const c2 = divNearest(-b1 * k, n); let k1 = k - c1 * a1 - c2 * a2; let k2 = -c1 * b1 - c2 * b2; const k1neg = k1 < _0n4; const k2neg = k2 < _0n4; if (k1neg) k1 = -k1; if (k2neg) k2 = -k2; const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n4; if (k1 < _0n4 || k1 >= MAX_NUM || k2 < _0n4 || k2 >= MAX_NUM) { throw new Error("splitScalar (endomorphism): failed, k=" + k); } return { k1neg, k1, k2neg, k2 }; } function validateSigFormat(format) { if (!["compact", "recovered", "der"].includes(format)) throw new Error('Signature format must be "compact", "recovered", or "der"'); return format; } function validateSigOpts(opts, def) { const optsn = {}; for (let optName of Object.keys(def)) { optsn[optName] = opts[optName] === void 0 ? def[optName] : opts[optName]; } abool(optsn.lowS, "lowS"); abool(optsn.prehash, "prehash"); if (optsn.format !== void 0) validateSigFormat(optsn.format); return optsn; } var DERErr = class extends Error { constructor(m = "") { super(m); } }; var DER = { Err: DERErr, _tlv: { encode: (tag, data) => { const { Err: E } = DER; if (tag < 0 || tag > 256) throw new E("tlv.encode: wrong tag"); if (data.length & 1) throw new E("tlv.encode: unpadded data"); const dataLen = data.length / 2; const len = numberToHexUnpadded(dataLen); if (len.length / 2 & 128) throw new E("tlv.encode: long form length too big"); const lenLen = dataLen > 127 ? numberToHexUnpadded(len.length / 2 | 128) : ""; const t = numberToHexUnpadded(tag); return t + lenLen + len + data; }, decode(tag, data) { const { Err: E } = DER; let pos = 0; if (tag < 0 || tag > 256) throw new E("tlv.encode: wrong tag"); if (data.length < 2 || data[pos++] !== tag) throw new E("tlv.decode: wrong tlv"); const first = data[pos++]; const isLong = !!(first & 128); let length = 0; if (!isLong) length = first; else { const lenLen = first & 127; if (!lenLen) throw new E("tlv.decode(long): indefinite length not supported"); if (lenLen > 4) throw new E("tlv.decode(long): byte length is too big"); const lengthBytes = data.subarray(pos, pos + lenLen); if (lengthBytes.length !== lenLen) throw new E("tlv.decode: length bytes not complete"); if (lengthBytes[0] === 0) throw new E("tlv.decode(long): zero leftmost byte"); for (const b of lengthBytes) length = length << 8 | b; pos += lenLen; if (length < 128) throw new E("tlv.decode(long): not minimal encoding"); } const v = data.subarray(pos, pos + length); if (v.length !== length) throw new E("tlv.decode: wrong value length"); return { v, l: data.subarray(pos + length) }; } }, _int: { encode(num2) { const { Err: E } = DER; if (num2 < _0n4) throw new E("integer: negative integers are not allowed"); let hex2 = numberToHexUnpadded(num2); if (Number.parseInt(hex2[0], 16) & 8) hex2 = "00" + hex2; if (hex2.length & 1) throw new E("unexpected DER parsing assertion: unpadded hex"); return hex2; }, decode(data) { const { Err: E } = DER; if (data[0] & 128) throw new E("invalid signature integer: negative"); if (data[0] === 0 && !(data[1] & 128)) throw new E("invalid signature integer: unnecessary leading zero"); return bytesToNumberBE(data); } }, toSig(bytes) { const { Err: E, _int: int, _tlv: tlv } = DER; const data = abytes(bytes, void 0, "signature"); const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data); if (seqLeftBytes.length) throw new E("invalid signature: left bytes after parsing"); const { v: rBytes, l: rLeftBytes } = tlv.decode(2, seqBytes); const { v: sBytes, l: sLeftBytes } = tlv.decode(2, rLeftBytes); if (sLeftBytes.length) throw new E("invalid signature: left bytes after parsing"); return { r: int.decode(rBytes), s: int.decode(sBytes) }; }, hexFromSig(sig) { const { _tlv: tlv, _int: int } = DER; const rs = tlv.encode(2, int.encode(sig.r)); const ss = tlv.encode(2, int.encode(sig.s)); const seq = rs + ss; return tlv.encode(48, seq); } }; var _0n4 = BigInt(0); var _1n4 = BigInt(1); var _2n2 = BigInt(2); var _3n2 = BigInt(3); var _4n2 = BigInt(4); function weierstrass(params, extraOpts = {}) { const validated = createCurveFields("weierstrass", params, extraOpts); const { Fp, Fn } = validated; let CURVE = validated.CURVE; const { h: cofactor, n: CURVE_ORDER } = CURVE; validateObject(extraOpts, {}, { allowInfinityPoint: "boolean", clearCofactor: "function", isTorsionFree: "function", fromBytes: "function", toBytes: "function", endo: "object" }); const { endo } = extraOpts; if (endo) { if (!Fp.is0(CURVE.a) || typeof endo.beta !== "bigint" || !Array.isArray(endo.basises)) { throw new Error('invalid endo: expected "beta": bigint and "basises": array'); } } const lengths = getWLengths(Fp, Fn); function assertCompressionIsSupported() { if (!Fp.isOdd) throw new Error("compression is not supported: Field does not have .isOdd()"); } function pointToBytes2(_c, point, isCompressed) { const { x, y } = point.toAffine(); const bx = Fp.toBytes(x); abool(isCompressed, "isCompressed"); if (isCompressed) { assertCompressionIsSupported(); const hasEvenY = !Fp.isOdd(y); return concatBytes(pprefix(hasEvenY), bx); } else { return concatBytes(Uint8Array.of(4), bx, Fp.toBytes(y)); } } function pointFromBytes(bytes) { abytes(bytes, void 0, "Point"); const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths; const length = bytes.length; const head = bytes[0]; const tail = bytes.subarray(1); if (length === comp && (head === 2 || head === 3)) { const x = Fp.fromBytes(tail); if (!Fp.isValid(x)) throw new Error("bad point: is not on curve, wrong x"); const y2 = weierstrassEquation(x); let y; try { y = Fp.sqrt(y2); } catch (sqrtError) { const err = sqrtError instanceof Error ? ": " + sqrtError.message : ""; throw new Error("bad point: is not on curve, sqrt error" + err); } assertCompressionIsSupported(); const evenY = Fp.isOdd(y); const evenH = (head & 1) === 1; if (evenH !== evenY) y = Fp.neg(y); return { x, y }; } else if (length === uncomp && head === 4) { const L = Fp.BYTES; const x = Fp.fromBytes(tail.subarray(0, L)); const y = Fp.fromBytes(tail.subarray(L, L * 2)); if (!isValidXY(x, y)) throw new Error("bad point: is not on curve"); return { x, y }; } else { throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`); } } const encodePoint = extraOpts.toBytes || pointToBytes2; const decodePoint = extraOpts.fromBytes || pointFromBytes; function weierstrassEquation(x) { const x2 = Fp.sqr(x); const x3 = Fp.mul(x2, x); return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b); } function isValidXY(x, y) { const left = Fp.sqr(y); const right = weierstrassEquation(x); return Fp.eql(left, right); } if (!isValidXY(CURVE.Gx, CURVE.Gy)) throw new Error("bad curve params: generator point"); const _4a3 = Fp.mul(Fp.pow(CURVE.a, _3n2), _4n2); const _27b2 = Fp.mul(Fp.sqr(CURVE.b), BigInt(27)); if (Fp.is0(Fp.add(_4a3, _27b2))) throw new Error("bad curve params: a or b"); function acoord(title, n, banZero = false) { if (!Fp.isValid(n) || banZero && Fp.is0(n)) throw new Error(`bad point coordinate ${title}`); return n; } function aprjpoint(other) { if (!(other instanceof Point)) throw new Error("Weierstrass Point expected"); } function splitEndoScalarN(k) { if (!endo || !endo.basises) throw new Error("no endo"); return _splitEndoScalar(k, endo.basises, Fn.ORDER); } const toAffineMemo = memoized((p, iz) => { const { X, Y, Z } = p; if (Fp.eql(Z, Fp.ONE)) return { x: X, y: Y }; const is0 = p.is0(); if (iz == null) iz = is0 ? Fp.ONE : Fp.inv(Z); const x = Fp.mul(X, iz); const y = Fp.mul(Y, iz); const zz = Fp.mul(Z, iz); if (is0) return { x: Fp.ZERO, y: Fp.ZERO }; if (!Fp.eql(zz, Fp.ONE)) throw new Error("invZ was invalid"); return { x, y }; }); const assertValidMemo = memoized((p) => { if (p.is0()) { if (extraOpts.allowInfinityPoint && !Fp.is0(p.Y)) return; throw new Error("bad point: ZERO"); } const { x, y } = p.toAffine(); if (!Fp.isValid(x) || !Fp.isValid(y)) throw new Error("bad point: x or y not field elements"); if (!isValidXY(x, y)) throw new Error("bad point: equation left != right"); if (!p.isTorsionFree()) throw new Error("bad point: not in prime-order subgroup"); return true; }); function finishEndo(endoBeta, k1p, k2p, k1neg, k2neg) { k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z); k1p = negateCt(k1neg, k1p); k2p = negateCt(k2neg, k2p); return k1p.add(k2p); } class Point { static BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE); static ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); static Fp = Fp; static Fn = Fn; X; Y; Z; constructor(X, Y, Z) { this.X = acoord("x", X); this.Y = acoord("y", Y, true); this.Z = acoord("z", Z); Object.freeze(this); } static CURVE() { return CURVE; } static fromAffine(p) { const { x, y } = p || {}; if (!p || !Fp.isValid(x) || !Fp.isValid(y)) throw new Error("invalid affine point"); if (p instanceof Point) throw new Error("projective point not allowed"); if (Fp.is0(x) && Fp.is0(y)) return Point.ZERO; return new Point(x, y, Fp.ONE); } static fromBytes(bytes) { const P = Point.fromAffine(decodePoint(abytes(bytes, void 0, "point"))); P.assertValidity(); return P; } static fromHex(hex2) { return Point.fromBytes(hexToBytes(hex2)); } get x() { return this.toAffine().x; } get y() { return this.toAffine().y; } precompute(windowSize = 8, isLazy = true) { wnaf.createCache(this, windowSize); if (!isLazy) this.multiply(_3n2); return this; } assertValidity() { assertValidMemo(this); } hasEvenY() { const { y } = this.toAffine(); if (!Fp.isOdd) throw new Error("Field doesn't support isOdd"); return !Fp.isOdd(y); } equals(other) { aprjpoint(other); const { X: X1, Y: Y1, Z: Z1 } = this; const { X: X2, Y: Y2, Z: Z2 } = other; const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1)); const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1)); return U1 && U2; } negate() { return new Point(this.X, Fp.neg(this.Y), this.Z); } double() { const { a, b } = CURVE; const b3 = Fp.mul(b, _3n2); const { X: X1, Y: Y1, Z: Z1 } = this; let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; let t0 = Fp.mul(X1, X1); let t1 = Fp.mul(Y1, Y1); let t2 = Fp.mul(Z1, Z1); let t3 = Fp.mul(X1, Y1); t3 = Fp.add(t3, t3); Z3 = Fp.mul(X1, Z1); Z3 = Fp.add(Z3, Z3); X3 = Fp.mul(a, Z3); Y3 = Fp.mul(b3, t2); Y3 = Fp.add(X3, Y3); X3 = Fp.sub(t1, Y3); Y3 = Fp.add(t1, Y3); Y3 = Fp.mul(X3, Y3); X3 = Fp.mul(t3, X3); Z3 = Fp.mul(b3, Z3); t2 = Fp.mul(a, t2); t3 = Fp.sub(t0, t2); t3 = Fp.mul(a, t3); t3 = Fp.add(t3, Z3); Z3 = Fp.add(t0, t0); t0 = Fp.add(Z3, t0); t0 = Fp.add(t0, t2); t0 = Fp.mul(t0, t3); Y3 = Fp.add(Y3, t0); t2 = Fp.mul(Y1, Z1); t2 = Fp.add(t2, t2); t0 = Fp.mul(t2, t3); X3 = Fp.sub(X3, t0); Z3 = Fp.mul(t2, t1); Z3 = Fp.add(Z3, Z3); Z3 = Fp.add(Z3, Z3); return new Point(X3, Y3, Z3); } add(other) { aprjpoint(other); const { X: X1, Y: Y1, Z: Z1 } = this; const { X: X2, Y: Y2, Z: Z2 } = other; let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; const a = CURVE.a; const b3 = Fp.mul(CURVE.b, _3n2); let t0 = Fp.mul(X1, X2); let t1 = Fp.mul(Y1, Y2); let t2 = Fp.mul(Z1, Z2); let t3 = Fp.add(X1, Y1); let t4 = Fp.add(X2, Y2); t3 = Fp.mul(t3, t4); t4 = Fp.add(t0, t1); t3 = Fp.sub(t3, t4); t4 = Fp.add(X1, Z1); let t5 = Fp.add(X2, Z2); t4 = Fp.mul(t4, t5); t5 = Fp.add(t0, t2); t4 = Fp.sub(t4, t5); t5 = Fp.add(Y1, Z1); X3 = Fp.add(Y2, Z2); t5 = Fp.mul(t5, X3); X3 = Fp.add(t1, t2); t5 = Fp.sub(t5, X3); Z3 = Fp.mul(a, t4); X3 = Fp.mul(b3, t2); Z3 = Fp.add(X3, Z3); X3 = Fp.sub(t1, Z3); Z3 = Fp.add(t1, Z3); Y3 = Fp.mul(X3, Z3); t1 = Fp.add(t0, t0); t1 = Fp.add(t1, t0); t2 = Fp.mul(a, t2); t4 = Fp.mul(b3, t4); t1 = Fp.add(t1, t2); t2 = Fp.sub(t0, t2); t2 = Fp.mul(a, t2); t4 = Fp.add(t4, t2); t0 = Fp.mul(t1, t4); Y3 = Fp.add(Y3, t0); t0 = Fp.mul(t5, t4); X3 = Fp.mul(t3, X3); X3 = Fp.sub(X3, t0); t0 = Fp.mul(t3, t1); Z3 = Fp.mul(t5, Z3); Z3 = Fp.add(Z3, t0); return new Point(X3, Y3, Z3); } subtract(other) { return this.add(other.negate()); } is0() { return this.equals(Point.ZERO); } multiply(scalar) { const { endo: endo2 } = extraOpts; if (!Fn.isValidNot0(scalar)) throw new Error("invalid scalar: out of range"); let point, fake; const mul3 = (n) => wnaf.cached(this, n, (p) => normalizeZ(Point, p)); if (endo2) { const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar); const { p: k1p, f: k1f } = mul3(k1); const { p: k2p, f: k2f } = mul3(k2); fake = k1f.add(k2f); point = finishEndo(endo2.beta, k1p, k2p, k1neg, k2neg); } else { const { p, f } = mul3(scalar); point = p; fake = f; } return normalizeZ(Point, [point, fake])[0]; } multiplyUnsafe(sc) { const { endo: endo2 } = extraOpts; const p = this; if (!Fn.isValid(sc)) throw new Error("invalid scalar: out of range"); if (sc === _0n4 || p.is0()) return Point.ZERO; if (sc === _1n4) return p; if (wnaf.hasCache(this)) return this.multiply(sc); if (endo2) { const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc); const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2); return finishEndo(endo2.beta, p1, p2, k1neg, k2neg); } else { return wnaf.unsafe(p, sc); } } toAffine(invertedZ) { return toAffineMemo(this, invertedZ); } isTorsionFree() { const { isTorsionFree } = extraOpts; if (cofactor === _1n4) return true; if (isTorsionFree) return isTorsionFree(Point, this); return wnaf.unsafe(this, CURVE_ORDER).is0(); } clearCofactor() { const { clearCofactor } = extraOpts; if (cofactor === _1n4) return this; if (clearCofactor) return clearCofactor(Point, this); return this.multiplyUnsafe(cofactor); } isSmallOrder() { return this.multiplyUnsafe(cofactor).is0(); } toBytes(isCompressed = true) { abool(isCompressed, "isCompressed"); this.assertValidity(); return encodePoint(Point, this, isCompressed); } toHex(isCompressed = true) { return bytesToHex(this.toBytes(isCompressed)); } toString() { return ``; } } const bits = Fn.BITS; const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits); Point.BASE.precompute(8); return Point; } function pprefix(hasEvenY) { return Uint8Array.of(hasEvenY ? 2 : 3); } function getWLengths(Fp, Fn) { return { secretKey: Fn.BYTES, publicKey: 1 + Fp.BYTES, publicKeyUncompressed: 1 + 2 * Fp.BYTES, publicKeyHasPrefix: true, signature: 2 * Fn.BYTES }; } function ecdh(Point, ecdhOpts = {}) { const { Fn } = Point; const randomBytes_ = ecdhOpts.randomBytes || randomBytes; const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) }); function isValidSecretKey(secretKey) { try { const num2 = Fn.fromBytes(secretKey); return Fn.isValidNot0(num2); } catch (error) { return false; } } function isValidPublicKey(publicKey, isCompressed) { const { publicKey: comp, publicKeyUncompressed } = lengths; try { const l = publicKey.length; if (isCompressed === true && l !== comp) return false; if (isCompressed === false && l !== publicKeyUncompressed) return false; return !!Point.fromBytes(publicKey); } catch (error) { return false; } } function randomSecretKey(seed = randomBytes_(lengths.seed)) { return mapHashToField(abytes(seed, lengths.seed, "seed"), Fn.ORDER); } function getPublicKey2(secretKey, isCompressed = true) { return Point.BASE.multiply(Fn.fromBytes(secretKey)).toBytes(isCompressed); } function isProbPub(item) { const { secretKey, publicKey, publicKeyUncompressed } = lengths; if (!isBytes(item)) return void 0; if ("_lengths" in Fn && Fn._lengths || secretKey === publicKey) return void 0; const l = abytes(item, void 0, "key").length; return l === publicKey || l === publicKeyUncompressed; } function getSharedSecret(secretKeyA, publicKeyB, isCompressed = true) { if (isProbPub(secretKeyA) === true) throw new Error("first arg must be private key"); if (isProbPub(publicKeyB) === false) throw new Error("second arg must be public key"); const s = Fn.fromBytes(secretKeyA); const b = Point.fromBytes(publicKeyB); return b.multiply(s).toBytes(isCompressed); } const utils = { isValidSecretKey, isValidPublicKey, randomSecretKey }; const keygen = createKeygen(randomSecretKey, getPublicKey2); return Object.freeze({ getPublicKey: getPublicKey2, getSharedSecret, keygen, Point, utils, lengths }); } function ecdsa(Point, hash, ecdsaOpts = {}) { ahash(hash); validateObject(ecdsaOpts, {}, { hmac: "function", lowS: "boolean", randomBytes: "function", bits2int: "function", bits2int_modN: "function" }); ecdsaOpts = Object.assign({}, ecdsaOpts); const randomBytes3 = ecdsaOpts.randomBytes || randomBytes; const hmac2 = ecdsaOpts.hmac || ((key, msg) => hmac(hash, key, msg)); const { Fp, Fn } = Point; const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn; const { keygen, getPublicKey: getPublicKey2, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts); const defaultSigOpts = { prehash: true, lowS: typeof ecdsaOpts.lowS === "boolean" ? ecdsaOpts.lowS : true, format: "compact", extraEntropy: false }; const hasLargeCofactor = CURVE_ORDER * _2n2 < Fp.ORDER; function isBiggerThanHalfOrder(number) { const HALF = CURVE_ORDER >> _1n4; return number > HALF; } function validateRS(title, num2) { if (!Fn.isValidNot0(num2)) throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`); return num2; } function assertSmallCofactor() { if (hasLargeCofactor) throw new Error('"recovered" sig type is not supported for cofactor >2 curves'); } function validateSigLength(bytes, format) { validateSigFormat(format); const size = lengths.signature; const sizer = format === "compact" ? size : format === "recovered" ? size + 1 : void 0; return abytes(bytes, sizer); } class Signature { r; s; recovery; constructor(r, s, recovery) { this.r = validateRS("r", r); this.s = validateRS("s", s); if (recovery != null) { assertSmallCofactor(); if (![0, 1, 2, 3].includes(recovery)) throw new Error("invalid recovery id"); this.recovery = recovery; } Object.freeze(this); } static fromBytes(bytes, format = defaultSigOpts.format) { validateSigLength(bytes, format); let recid; if (format === "der") { const { r: r2, s: s2 } = DER.toSig(abytes(bytes)); return new Signature(r2, s2); } if (format === "recovered") { recid = bytes[0]; format = "compact"; bytes = bytes.subarray(1); } const L = lengths.signature / 2; const r = bytes.subarray(0, L); const s = bytes.subarray(L, L * 2); return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid); } static fromHex(hex2, format) { return this.fromBytes(hexToBytes(hex2), format); } assertRecovery() { const { recovery } = this; if (recovery == null) throw new Error("invalid recovery id: must be present"); return recovery; } addRecoveryBit(recovery) { return new Signature(this.r, this.s, recovery); } recoverPublicKey(messageHash) { const { r, s } = this; const recovery = this.assertRecovery(); const radj = recovery === 2 || recovery === 3 ? r + CURVE_ORDER : r; if (!Fp.isValid(radj)) throw new Error("invalid recovery id: sig.r+curve.n != R.x"); const x = Fp.toBytes(radj); const R = Point.fromBytes(concatBytes(pprefix((recovery & 1) === 0), x)); const ir = Fn.inv(radj); const h = bits2int_modN(abytes(messageHash, void 0, "msgHash")); const u1 = Fn.create(-h * ir); const u2 = Fn.create(s * ir); const Q = Point.BASE.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2)); if (Q.is0()) throw new Error("invalid recovery: point at infinify"); Q.assertValidity(); return Q; } hasHighS() { return isBiggerThanHalfOrder(this.s); } toBytes(format = defaultSigOpts.format) { validateSigFormat(format); if (format === "der") return hexToBytes(DER.hexFromSig(this)); const { r, s } = this; const rb = Fn.toBytes(r); const sb = Fn.toBytes(s); if (format === "recovered") { assertSmallCofactor(); return concatBytes(Uint8Array.of(this.assertRecovery()), rb, sb); } return concatBytes(rb, sb); } toHex(format) { return bytesToHex(this.toBytes(format)); } } const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) { if (bytes.length > 8192) throw new Error("input is too large"); const num2 = bytesToNumberBE(bytes); const delta = bytes.length * 8 - fnBits; return delta > 0 ? num2 >> BigInt(delta) : num2; }; const bits2int_modN = ecdsaOpts.bits2int_modN || function bits2int_modN_def(bytes) { return Fn.create(bits2int(bytes)); }; const ORDER_MASK = bitMask(fnBits); function int2octets(num2) { aInRange("num < 2^" + fnBits, num2, _0n4, ORDER_MASK); return Fn.toBytes(num2); } function validateMsgAndHash(message, prehash) { abytes(message, void 0, "message"); return prehash ? abytes(hash(message), void 0, "prehashed message") : message; } function prepSig(message, secretKey, opts) { const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts); message = validateMsgAndHash(message, prehash); const h1int = bits2int_modN(message); const d = Fn.fromBytes(secretKey); if (!Fn.isValidNot0(d)) throw new Error("invalid private key"); const seedArgs = [int2octets(d), int2octets(h1int)]; if (extraEntropy != null && extraEntropy !== false) { const e = extraEntropy === true ? randomBytes3(lengths.secretKey) : extraEntropy; seedArgs.push(abytes(e, void 0, "extraEntropy")); } const seed = concatBytes(...seedArgs); const m = h1int; function k2sig(kBytes) { const k = bits2int(kBytes); if (!Fn.isValidNot0(k)) return; const ik = Fn.inv(k); const q = Point.BASE.multiply(k).toAffine(); const r = Fn.create(q.x); if (r === _0n4) return; const s = Fn.create(ik * Fn.create(m + r * d)); if (s === _0n4) return; let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n4); let normS = s; if (lowS && isBiggerThanHalfOrder(s)) { normS = Fn.neg(s); recovery ^= 1; } return new Signature(r, normS, hasLargeCofactor ? void 0 : recovery); } return { seed, k2sig }; } function sign(message, secretKey, opts = {}) { const { seed, k2sig } = prepSig(message, secretKey, opts); const drbg = createHmacDrbg(hash.outputLen, Fn.BYTES, hmac2); const sig = drbg(seed, k2sig); return sig.toBytes(opts.format); } function verify(signature, message, publicKey, opts = {}) { const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts); publicKey = abytes(publicKey, void 0, "publicKey"); message = validateMsgAndHash(message, prehash); if (!isBytes(signature)) { const end = signature instanceof Signature ? ", use sig.toBytes()" : ""; throw new Error("verify expects Uint8Array signature" + end); } validateSigLength(signature, format); try { const sig = Signature.fromBytes(signature, format); const P = Point.fromBytes(publicKey); if (lowS && sig.hasHighS()) return false; const { r, s } = sig; const h = bits2int_modN(message); const is = Fn.inv(s); const u1 = Fn.create(h * is); const u2 = Fn.create(r * is); const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2)); if (R.is0()) return false; const v = Fn.create(R.x); return v === r; } catch (e) { return false; } } function recoverPublicKey(signature, message, opts = {}) { const { prehash } = validateSigOpts(opts, defaultSigOpts); message = validateMsgAndHash(message, prehash); return Signature.fromBytes(signature, "recovered").recoverPublicKey(message).toBytes(); } return Object.freeze({ keygen, getPublicKey: getPublicKey2, getSharedSecret, utils, lengths, Point, sign, verify, recoverPublicKey, Signature, hash }); } // node_modules/@noble/curves/secp256k1.js var secp256k1_CURVE = { p: BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"), n: BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), h: BigInt(1), a: BigInt(0), b: BigInt(7), Gx: BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), Gy: BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8") }; var secp256k1_ENDO = { beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"), basises: [ [BigInt("0x3086d221a7d46bcde86c90e49284eb15"), -BigInt("0xe4437ed6010e88286f547fa90abfe4c3")], [BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"), BigInt("0x3086d221a7d46bcde86c90e49284eb15")] ] }; var _0n5 = /* @__PURE__ */ BigInt(0); var _2n3 = /* @__PURE__ */ BigInt(2); function sqrtMod(y) { const P = secp256k1_CURVE.p; const _3n3 = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22); const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88); const b2 = y * y * y % P; const b3 = b2 * b2 * y % P; const b6 = pow2(b3, _3n3, P) * b3 % P; const b9 = pow2(b6, _3n3, P) * b3 % P; const b11 = pow2(b9, _2n3, P) * b2 % P; const b22 = pow2(b11, _11n, P) * b11 % P; const b44 = pow2(b22, _22n, P) * b22 % P; const b88 = pow2(b44, _44n, P) * b44 % P; const b176 = pow2(b88, _88n, P) * b88 % P; const b220 = pow2(b176, _44n, P) * b44 % P; const b223 = pow2(b220, _3n3, P) * b3 % P; const t1 = pow2(b223, _23n, P) * b22 % P; const t2 = pow2(t1, _6n, P) * b2 % P; const root = pow2(t2, _2n3, P); if (!Fpk1.eql(Fpk1.sqr(root), y)) throw new Error("Cannot find square root"); return root; } var Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod }); var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, { Fp: Fpk1, endo: secp256k1_ENDO }); var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha256); var TAGGED_HASH_PREFIXES = {}; function taggedHash(tag, ...messages) { let tagP = TAGGED_HASH_PREFIXES[tag]; if (tagP === void 0) { const tagH = sha256(asciiToBytes(tag)); tagP = concatBytes(tagH, tagH); TAGGED_HASH_PREFIXES[tag] = tagP; } return sha256(concatBytes(tagP, ...messages)); } var pointToBytes = (point) => point.toBytes(true).slice(1); var hasEven = (y) => y % _2n3 === _0n5; function schnorrGetExtPubKey(priv) { const { Fn, BASE } = Pointk1; const d_ = Fn.fromBytes(priv); const p = BASE.multiply(d_); const scalar = hasEven(p.y) ? d_ : Fn.neg(d_); return { scalar, bytes: pointToBytes(p) }; } function lift_x(x) { const Fp = Fpk1; if (!Fp.isValidNot0(x)) throw new Error("invalid x: Fail if x \u2265 p"); const xx = Fp.create(x * x); const c = Fp.create(xx * x + BigInt(7)); let y = Fp.sqrt(c); if (!hasEven(y)) y = Fp.neg(y); const p = Pointk1.fromAffine({ x, y }); p.assertValidity(); return p; } var num = bytesToNumberBE; function challenge(...args) { return Pointk1.Fn.create(num(taggedHash("BIP0340/challenge", ...args))); } function schnorrGetPublicKey(secretKey) { return schnorrGetExtPubKey(secretKey).bytes; } function schnorrSign(message, secretKey, auxRand = randomBytes(32)) { const { Fn } = Pointk1; const m = abytes(message, void 0, "message"); const { bytes: px, scalar: d } = schnorrGetExtPubKey(secretKey); const a = abytes(auxRand, 32, "auxRand"); const t = Fn.toBytes(d ^ num(taggedHash("BIP0340/aux", a))); const rand = taggedHash("BIP0340/nonce", t, px, m); const { bytes: rx, scalar: k } = schnorrGetExtPubKey(rand); const e = challenge(rx, px, m); const sig = new Uint8Array(64); sig.set(rx, 0); sig.set(Fn.toBytes(Fn.create(k + e * d)), 32); if (!schnorrVerify(sig, m, px)) throw new Error("sign: Invalid signature produced"); return sig; } function schnorrVerify(signature, message, publicKey) { const { Fp, Fn, BASE } = Pointk1; const sig = abytes(signature, 64, "signature"); const m = abytes(message, void 0, "message"); const pub = abytes(publicKey, 32, "publicKey"); try { const P = lift_x(num(pub)); const r = num(sig.subarray(0, 32)); if (!Fp.isValidNot0(r)) return false; const s = num(sig.subarray(32, 64)); if (!Fn.isValidNot0(s)) return false; const e = challenge(Fn.toBytes(r), pointToBytes(P), m); const R = BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(Fn.neg(e))); const { x, y } = R.toAffine(); if (R.is0() || !hasEven(y) || x !== r) return false; return true; } catch (error) { return false; } } var schnorr = /* @__PURE__ */ (() => { const size = 32; const seedLength = 48; const randomSecretKey = (seed = randomBytes(seedLength)) => { return mapHashToField(seed, secp256k1_CURVE.n); }; return { keygen: createKeygen(randomSecretKey, schnorrGetPublicKey), getPublicKey: schnorrGetPublicKey, sign: schnorrSign, verify: schnorrVerify, Point: Pointk1, utils: { randomSecretKey, taggedHash, lift_x, pointToBytes }, lengths: { secretKey: size, publicKey: size, publicKeyHasPrefix: false, signature: size * 2, seed: seedLength } }; })(); // core.ts var verifiedSymbol = Symbol("verified"); var isRecord = (obj) => obj instanceof Object; function validateEvent(event) { if (!isRecord(event)) return false; if (typeof event.kind !== "number") return false; if (typeof event.content !== "string") return false; if (typeof event.created_at !== "number") return false; if (typeof event.pubkey !== "string") return false; if (!event.pubkey.match(/^[a-f0-9]{64}$/)) return false; if (!Array.isArray(event.tags)) return false; for (let i2 = 0; i2 < event.tags.length; i2++) { let tag = event.tags[i2]; if (!Array.isArray(tag)) return false; for (let j = 0; j < tag.length; j++) { if (typeof tag[j] !== "string") return false; } } return true; } function sortEvents(events) { return events.sort((a, b) => { if (a.created_at !== b.created_at) { return b.created_at - a.created_at; } return a.id.localeCompare(b.id); }); } // utils.ts var utils_exports = {}; __export(utils_exports, { binarySearch: () => binarySearch, bytesToHex: () => bytesToHex, hexToBytes: () => hexToBytes, insertEventIntoAscendingList: () => insertEventIntoAscendingList, insertEventIntoDescendingList: () => insertEventIntoDescendingList, mergeReverseSortedLists: () => mergeReverseSortedLists, normalizeURL: () => normalizeURL, utf8Decoder: () => utf8Decoder, utf8Encoder: () => utf8Encoder }); var utf8Decoder = new TextDecoder("utf-8"); var utf8Encoder = new TextEncoder(); function normalizeURL(url) { try { if (url.indexOf("://") === -1) url = "wss://" + url; let p = new URL(url); if (p.protocol === "http:") p.protocol = "ws:"; else if (p.protocol === "https:") p.protocol = "wss:"; p.pathname = p.pathname.replace(/\/+/g, "/"); if (p.pathname.endsWith("/")) p.pathname = p.pathname.slice(0, -1); if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:") p.port = ""; p.searchParams.sort(); p.hash = ""; return p.toString(); } catch (e) { throw new Error(`Invalid URL: ${url}`); } } function insertEventIntoDescendingList(sortedArray, event) { const [idx, found] = binarySearch(sortedArray, (b) => { if (event.id === b.id) return 0; if (event.created_at === b.created_at) return -1; return b.created_at - event.created_at; }); if (!found) { sortedArray.splice(idx, 0, event); } return sortedArray; } function insertEventIntoAscendingList(sortedArray, event) { const [idx, found] = binarySearch(sortedArray, (b) => { if (event.id === b.id) return 0; if (event.created_at === b.created_at) return -1; return event.created_at - b.created_at; }); if (!found) { sortedArray.splice(idx, 0, event); } return sortedArray; } function binarySearch(arr, compare) { let start = 0; let end = arr.length - 1; while (start <= end) { const mid = Math.floor((start + end) / 2); const cmp = compare(arr[mid]); if (cmp === 0) { return [mid, true]; } if (cmp < 0) { end = mid - 1; } else { start = mid + 1; } } return [start, false]; } function mergeReverseSortedLists(list1, list2) { const result = new Array(list1.length + list2.length); result.length = 0; let i1 = 0; let i2 = 0; let sameTimestampIds = []; while (i1 < list1.length && i2 < list2.length) { let next; if (list1[i1]?.created_at > list2[i2]?.created_at) { next = list1[i1]; i1++; } else { next = list2[i2]; i2++; } if (result.length > 0 && result[result.length - 1].created_at === next.created_at) { if (sameTimestampIds.includes(next.id)) continue; } else { sameTimestampIds.length = 0; } result.push(next); sameTimestampIds.push(next.id); } while (i1 < list1.length) { const next = list1[i1]; i1++; if (result.length > 0 && result[result.length - 1].created_at === next.created_at) { if (sameTimestampIds.includes(next.id)) continue; } else { sameTimestampIds.length = 0; } result.push(next); sameTimestampIds.push(next.id); } while (i2 < list2.length) { const next = list2[i2]; i2++; if (result.length > 0 && result[result.length - 1].created_at === next.created_at) { if (sameTimestampIds.includes(next.id)) continue; } else { sameTimestampIds.length = 0; } result.push(next); sameTimestampIds.push(next.id); } return result; } // pure.ts var JS = class { generateSecretKey() { return schnorr.utils.randomSecretKey(); } getPublicKey(secretKey) { return bytesToHex(schnorr.getPublicKey(secretKey)); } finalizeEvent(t, secretKey) { const event = t; event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey)); event.id = getEventHash(event); event.sig = bytesToHex(schnorr.sign(hexToBytes(getEventHash(event)), secretKey)); event[verifiedSymbol] = true; return event; } verifyEvent(event) { if (typeof event[verifiedSymbol] === "boolean") return event[verifiedSymbol]; const hash = getEventHash(event); if (hash !== event.id) { event[verifiedSymbol] = false; return false; } try { const valid = schnorr.verify(hexToBytes(event.sig), hexToBytes(hash), hexToBytes(event.pubkey)); event[verifiedSymbol] = valid; return valid; } catch (err) { event[verifiedSymbol] = false; return false; } } }; function serializeEvent(evt) { if (!validateEvent(evt)) throw new Error("can't serialize event with wrong or missing properties"); return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]); } function getEventHash(event) { let eventHash = sha256(utf8Encoder.encode(serializeEvent(event))); return bytesToHex(eventHash); } var i = new JS(); var generateSecretKey = i.generateSecretKey; var getPublicKey = i.getPublicKey; var finalizeEvent = i.finalizeEvent; var verifyEvent = i.verifyEvent; // kinds.ts var kinds_exports = {}; __export(kinds_exports, { Application: () => Application, BadgeAward: () => BadgeAward, BadgeDefinition: () => BadgeDefinition, BlockedRelaysList: () => BlockedRelaysList, BlossomServerList: () => BlossomServerList, BookmarkList: () => BookmarkList, Bookmarksets: () => Bookmarksets, Calendar: () => Calendar, CalendarEventRSVP: () => CalendarEventRSVP, ChannelCreation: () => ChannelCreation, ChannelHideMessage: () => ChannelHideMessage, ChannelMessage: () => ChannelMessage, ChannelMetadata: () => ChannelMetadata, ChannelMuteUser: () => ChannelMuteUser, ChatMessage: () => ChatMessage, ClassifiedListing: () => ClassifiedListing, ClientAuth: () => ClientAuth, Comment: () => Comment, CommunitiesList: () => CommunitiesList, CommunityDefinition: () => CommunityDefinition, CommunityPostApproval: () => CommunityPostApproval, Contacts: () => Contacts, CreateOrUpdateProduct: () => CreateOrUpdateProduct, CreateOrUpdateStall: () => CreateOrUpdateStall, Curationsets: () => Curationsets, Date: () => Date2, DirectMessageRelaysList: () => DirectMessageRelaysList, DraftClassifiedListing: () => DraftClassifiedListing, DraftLong: () => DraftLong, Emojisets: () => Emojisets, EncryptedDirectMessage: () => EncryptedDirectMessage, EventDeletion: () => EventDeletion, FavoriteRelays: () => FavoriteRelays, FileMessage: () => FileMessage, FileMetadata: () => FileMetadata, FileServerPreference: () => FileServerPreference, Followsets: () => Followsets, ForumThread: () => ForumThread, GenericRepost: () => GenericRepost, Genericlists: () => Genericlists, GiftWrap: () => GiftWrap, GroupMetadata: () => GroupMetadata, HTTPAuth: () => HTTPAuth, Handlerinformation: () => Handlerinformation, Handlerrecommendation: () => Handlerrecommendation, Highlights: () => Highlights, InterestsList: () => InterestsList, Interestsets: () => Interestsets, JobFeedback: () => JobFeedback, JobRequest: () => JobRequest, JobResult: () => JobResult, Label: () => Label, LightningPubRPC: () => LightningPubRPC, LiveChatMessage: () => LiveChatMessage, LiveEvent: () => LiveEvent, LongFormArticle: () => LongFormArticle, Metadata: () => Metadata, Mutelist: () => Mutelist, NWCWalletInfo: () => NWCWalletInfo, NWCWalletRequest: () => NWCWalletRequest, NWCWalletResponse: () => NWCWalletResponse, NormalVideo: () => NormalVideo, NostrConnect: () => NostrConnect, OpenTimestamps: () => OpenTimestamps, Photo: () => Photo, Pinlist: () => Pinlist, Poll: () => Poll, PollResponse: () => PollResponse, PrivateDirectMessage: () => PrivateDirectMessage, ProblemTracker: () => ProblemTracker, ProfileBadges: () => ProfileBadges, PublicChatsList: () => PublicChatsList, Reaction: () => Reaction, RecommendRelay: () => RecommendRelay, RelayList: () => RelayList, RelayReview: () => RelayReview, Relaysets: () => Relaysets, Report: () => Report, Reporting: () => Reporting, Repost: () => Repost, Seal: () => Seal, SearchRelaysList: () => SearchRelaysList, ShortTextNote: () => ShortTextNote, ShortVideo: () => ShortVideo, Time: () => Time, UserEmojiList: () => UserEmojiList, UserStatuses: () => UserStatuses, Voice: () => Voice, VoiceComment: () => VoiceComment, Zap: () => Zap, ZapGoal: () => ZapGoal, ZapRequest: () => ZapRequest, classifyKind: () => classifyKind, isAddressableKind: () => isAddressableKind, isEphemeralKind: () => isEphemeralKind, isKind: () => isKind, isRegularKind: () => isRegularKind, isReplaceableKind: () => isReplaceableKind }); function isRegularKind(kind) { return kind < 1e4 && kind !== 0 && kind !== 3; } function isReplaceableKind(kind) { return kind === 0 || kind === 3 || 1e4 <= kind && kind < 2e4; } function isEphemeralKind(kind) { return 2e4 <= kind && kind < 3e4; } function isAddressableKind(kind) { return 3e4 <= kind && kind < 4e4; } function classifyKind(kind) { if (isRegularKind(kind)) return "regular"; if (isReplaceableKind(kind)) return "replaceable"; if (isEphemeralKind(kind)) return "ephemeral"; if (isAddressableKind(kind)) return "parameterized"; return "unknown"; } function isKind(event, kind) { const kindAsArray = kind instanceof Array ? kind : [kind]; return validateEvent(event) && kindAsArray.includes(event.kind) || false; } var Metadata = 0; var ShortTextNote = 1; var RecommendRelay = 2; var Contacts = 3; var EncryptedDirectMessage = 4; var EventDeletion = 5; var Repost = 6; var Reaction = 7; var BadgeAward = 8; var ChatMessage = 9; var ForumThread = 11; var Seal = 13; var PrivateDirectMessage = 14; var FileMessage = 15; var GenericRepost = 16; var Photo = 20; var NormalVideo = 21; var ShortVideo = 22; var ChannelCreation = 40; var ChannelMetadata = 41; var ChannelMessage = 42; var ChannelHideMessage = 43; var ChannelMuteUser = 44; var OpenTimestamps = 1040; var GiftWrap = 1059; var Poll = 1068; var FileMetadata = 1063; var Comment = 1111; var LiveChatMessage = 1311; var Voice = 1222; var VoiceComment = 1244; var ProblemTracker = 1971; var Report = 1984; var Reporting = 1984; var Label = 1985; var CommunityPostApproval = 4550; var JobRequest = 5999; var JobResult = 6999; var JobFeedback = 7e3; var ZapGoal = 9041; var ZapRequest = 9734; var Zap = 9735; var Highlights = 9802; var PollResponse = 1018; var Mutelist = 1e4; var Pinlist = 10001; var RelayList = 10002; var BookmarkList = 10003; var CommunitiesList = 10004; var PublicChatsList = 10005; var BlockedRelaysList = 10006; var SearchRelaysList = 10007; var FavoriteRelays = 10012; var InterestsList = 10015; var UserEmojiList = 10030; var DirectMessageRelaysList = 10050; var FileServerPreference = 10096; var BlossomServerList = 10063; var NWCWalletInfo = 13194; var LightningPubRPC = 21e3; var ClientAuth = 22242; var NWCWalletRequest = 23194; var NWCWalletResponse = 23195; var NostrConnect = 24133; var HTTPAuth = 27235; var Followsets = 3e4; var Genericlists = 30001; var Relaysets = 30002; var Bookmarksets = 30003; var Curationsets = 30004; var ProfileBadges = 30008; var BadgeDefinition = 30009; var Interestsets = 30015; var CreateOrUpdateStall = 30017; var CreateOrUpdateProduct = 30018; var LongFormArticle = 30023; var DraftLong = 30024; var Emojisets = 30030; var Application = 30078; var LiveEvent = 30311; var UserStatuses = 30315; var ClassifiedListing = 30402; var DraftClassifiedListing = 30403; var Date2 = 31922; var Time = 31923; var Calendar = 31924; var CalendarEventRSVP = 31925; var RelayReview = 31987; var Handlerrecommendation = 31989; var Handlerinformation = 31990; var CommunityDefinition = 34550; var GroupMetadata = 39e3; // filter.ts function matchFilter(filter, event) { if (filter.ids && filter.ids.indexOf(event.id) === -1) { return false; } if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) { return false; } if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) { return false; } for (let f in filter) { if (f[0] === "#") { let tagName = f.slice(1); let values = filter[`#${tagName}`]; if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1)) return false; } } if (filter.since && event.created_at < filter.since) return false; if (filter.until && event.created_at > filter.until) return false; return true; } function matchFilters(filters, event) { for (let i2 = 0; i2 < filters.length; i2++) { if (matchFilter(filters[i2], event)) { return true; } } return false; } function mergeFilters(...filters) { let result = {}; for (let i2 = 0; i2 < filters.length; i2++) { let filter = filters[i2]; Object.entries(filter).forEach(([property, values]) => { if (property === "kinds" || property === "ids" || property === "authors" || property[0] === "#") { result[property] = result[property] || []; for (let v = 0; v < values.length; v++) { let value = values[v]; if (!result[property].includes(value)) result[property].push(value); } } }); if (filter.limit && (!result.limit || filter.limit > result.limit)) result.limit = filter.limit; if (filter.until && (!result.until || filter.until > result.until)) result.until = filter.until; if (filter.since && (!result.since || filter.since < result.since)) result.since = filter.since; } return result; } function getFilterLimit(filter) { if (filter.ids && !filter.ids.length) return 0; if (filter.kinds && !filter.kinds.length) return 0; if (filter.authors && !filter.authors.length) return 0; for (const [key, value] of Object.entries(filter)) { if (key[0] === "#" && Array.isArray(value) && !value.length) return 0; } return Math.min( Math.max(0, filter.limit ?? Infinity), filter.ids?.length ?? Infinity, filter.authors?.length && filter.kinds?.every((kind) => isReplaceableKind(kind)) ? filter.authors.length * filter.kinds.length : Infinity, filter.authors?.length && filter.kinds?.every((kind) => isAddressableKind(kind)) && filter["#d"]?.length ? filter.authors.length * filter.kinds.length * filter["#d"].length : Infinity ); } // fakejson.ts var fakejson_exports = {}; __export(fakejson_exports, { getHex64: () => getHex64, getInt: () => getInt, getSubscriptionId: () => getSubscriptionId, matchEventId: () => matchEventId, matchEventKind: () => matchEventKind, matchEventPubkey: () => matchEventPubkey }); function getHex64(json, field) { let len = field.length + 3; let idx = json.indexOf(`"${field}":`) + len; let s = json.slice(idx).indexOf(`"`) + idx + 1; return json.slice(s, s + 64); } function getInt(json, field) { let len = field.length; let idx = json.indexOf(`"${field}":`) + len + 3; let sliced = json.slice(idx); let end = Math.min(sliced.indexOf(","), sliced.indexOf("}")); return parseInt(sliced.slice(0, end), 10); } function getSubscriptionId(json) { let idx = json.slice(0, 22).indexOf(`"EVENT"`); if (idx === -1) return null; let pstart = json.slice(idx + 7 + 1).indexOf(`"`); if (pstart === -1) return null; let start = idx + 7 + 1 + pstart; let pend = json.slice(start + 1, 80).indexOf(`"`); if (pend === -1) return null; let end = start + 1 + pend; return json.slice(start + 1, end); } function matchEventId(json, id) { return id === getHex64(json, "id"); } function matchEventPubkey(json, pubkey) { return pubkey === getHex64(json, "pubkey"); } function matchEventKind(json, kind) { return kind === getInt(json, "kind"); } // nip42.ts var nip42_exports = {}; __export(nip42_exports, { makeAuthEvent: () => makeAuthEvent }); function makeAuthEvent(relayURL, challenge2) { return { kind: ClientAuth, created_at: Math.floor(Date.now() / 1e3), tags: [ ["relay", relayURL], ["challenge", challenge2] ], content: "" }; } // abstract-relay.ts var SendingOnClosedConnection = class extends Error { constructor(message, relay) { super(`Tried to send message '${message} on a closed connection to ${relay}.`); this.name = "SendingOnClosedConnection"; } }; var AbstractRelay = class { url; _connected = false; onclose = null; onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`); onauth; baseEoseTimeout = 4400; publishTimeout = 4400; pingFrequency = 29e3; pingTimeout = 2e4; resubscribeBackoff = [1e4, 1e4, 1e4, 2e4, 2e4, 3e4, 6e4]; openSubs = /* @__PURE__ */ new Map(); enablePing; enableReconnect; idleSince = Date.now(); ongoingOperations = 0; reconnectTimeoutHandle; pingIntervalHandle; reconnectAttempts = 0; skipReconnection = false; connectionPromise; openCountRequests = /* @__PURE__ */ new Map(); openEventPublishes = /* @__PURE__ */ new Map(); ws; challenge; authPromise; serial = 0; verifyEvent; _WebSocket; constructor(url, opts) { this.url = normalizeURL(url); this.verifyEvent = opts.verifyEvent; this._WebSocket = opts.websocketImplementation || WebSocket; this.enablePing = opts.enablePing; this.enableReconnect = opts.enableReconnect || false; } static async connect(url, opts) { const relay = new AbstractRelay(url, opts); await relay.connect(opts); return relay; } closeAllSubscriptions(reason) { for (let [_, sub] of this.openSubs) { sub.close(reason); } this.openSubs.clear(); for (let [_, ep] of this.openEventPublishes) { ep.reject(new Error(reason)); } this.openEventPublishes.clear(); for (let [_, cr] of this.openCountRequests) { cr.reject(new Error(reason)); } this.openCountRequests.clear(); } get connected() { return this._connected; } async reconnect() { const backoff = this.resubscribeBackoff[Math.min(this.reconnectAttempts, this.resubscribeBackoff.length - 1)]; this.reconnectAttempts++; this.reconnectTimeoutHandle = setTimeout(async () => { try { await this.connect(); } catch (err) { } }, backoff); } handleHardClose(reason) { if (this.pingIntervalHandle) { clearInterval(this.pingIntervalHandle); this.pingIntervalHandle = void 0; } this._connected = false; this.connectionPromise = void 0; this.idleSince = void 0; if (this.enableReconnect && !this.skipReconnection) { this.reconnect(); } else { this.onclose?.(); this.closeAllSubscriptions(reason); } } async connect(opts) { let connectionTimeoutHandle; if (this.connectionPromise) return this.connectionPromise; this.challenge = void 0; this.authPromise = void 0; this.skipReconnection = false; this.connectionPromise = new Promise((resolve, reject) => { if (opts?.timeout) { connectionTimeoutHandle = setTimeout(() => { reject("connection timed out"); this.connectionPromise = void 0; this.skipReconnection = true; this.onclose?.(); this.handleHardClose("relay connection timed out"); }, opts.timeout); } if (opts?.abort) { opts.abort.onabort = reject; } try { this.ws = new this._WebSocket(this.url); } catch (err) { clearTimeout(connectionTimeoutHandle); reject(err); return; } this.ws.onopen = () => { if (this.reconnectTimeoutHandle) { clearTimeout(this.reconnectTimeoutHandle); this.reconnectTimeoutHandle = void 0; } clearTimeout(connectionTimeoutHandle); this._connected = true; const isReconnection = this.reconnectAttempts > 0; this.reconnectAttempts = 0; for (const sub of this.openSubs.values()) { sub.eosed = false; if (isReconnection) { for (let f = 0; f < sub.filters.length; f++) { if (sub.lastEmitted) { sub.filters[f].since = sub.lastEmitted + 1; } } } sub.fire(); } if (this.enablePing) { this.pingIntervalHandle = setInterval(() => this.pingpong(), this.pingFrequency); } resolve(); }; this.ws.onerror = () => { clearTimeout(connectionTimeoutHandle); reject("connection failed"); this.connectionPromise = void 0; this.skipReconnection = true; this.onclose?.(); this.handleHardClose("relay connection failed"); }; this.ws.onclose = (ev) => { clearTimeout(connectionTimeoutHandle); reject(ev.message || "websocket closed"); this.handleHardClose("relay connection closed"); }; this.ws.onmessage = this._onmessage.bind(this); }); return this.connectionPromise; } waitForPingPong() { return new Promise((resolve) => { ; this.ws.once("pong", () => resolve(true)); this.ws.ping(); }); } waitForDummyReq() { return new Promise((resolve, reject) => { if (!this.connectionPromise) return reject(new Error(`no connection to ${this.url}, can't ping`)); try { const sub = this.subscribe( [{ ids: ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], limit: 0 }], { label: "", oneose: () => { resolve(true); sub.close(); }, onclose() { resolve(true); }, eoseTimeout: this.pingTimeout + 1e3 } ); } catch (err) { reject(err); } }); } async pingpong() { if (this.ws?.readyState === 1) { const result = await Promise.any([ this.ws && this.ws.ping && this.ws.once ? this.waitForPingPong() : this.waitForDummyReq(), new Promise((res) => setTimeout(() => res(false), this.pingTimeout)) ]); if (!result) { if (this.ws?.readyState === this._WebSocket.OPEN) { this.ws?.close(); } } } } async send(message) { if (!this.connectionPromise) throw new SendingOnClosedConnection(message, this.url); this.connectionPromise.then(() => { this.ws?.send(message); }); } async auth(signAuthEvent) { const challenge2 = this.challenge; if (!challenge2) throw new Error("can't perform auth, no challenge was received"); if (this.authPromise) return this.authPromise; this.authPromise = new Promise(async (resolve, reject) => { try { let evt = await signAuthEvent(makeAuthEvent(this.url, challenge2)); let timeout = setTimeout(() => { let ep = this.openEventPublishes.get(evt.id); if (ep) { ep.reject(new Error("auth timed out")); this.openEventPublishes.delete(evt.id); } }, this.publishTimeout); this.openEventPublishes.set(evt.id, { resolve, reject, timeout }); this.send('["AUTH",' + JSON.stringify(evt) + "]"); } catch (err) { console.warn("subscribe auth function failed:", err); } }); return this.authPromise; } async publish(event) { this.idleSince = void 0; this.ongoingOperations++; const ret = new Promise((resolve, reject) => { const timeout = setTimeout(() => { const ep = this.openEventPublishes.get(event.id); if (ep) { ep.reject(new Error("publish timed out")); this.openEventPublishes.delete(event.id); } }, this.publishTimeout); this.openEventPublishes.set(event.id, { resolve, reject, timeout }); }); this.send('["EVENT",' + JSON.stringify(event) + "]"); this.ongoingOperations--; if (this.ongoingOperations === 0) this.idleSince = Date.now(); return ret; } async count(filters, params) { this.serial++; const id = params?.id || "count:" + this.serial; const ret = new Promise((resolve, reject) => { this.openCountRequests.set(id, { resolve, reject }); }); this.send('["COUNT","' + id + '",' + JSON.stringify(filters).substring(1)); return ret; } subscribe(filters, params) { if (params.label !== "") { this.idleSince = void 0; this.ongoingOperations++; } const sub = this.prepareSubscription(filters, params); sub.fire(); if (params.abort) { params.abort.onabort = () => sub.close(String(params.abort.reason || "")); } return sub; } prepareSubscription(filters, params) { this.serial++; const id = params.id || (params.label ? params.label + ":" : "sub:") + this.serial; const sub = new Subscription(this, id, filters, params); this.openSubs.set(id, sub); return sub; } close() { this.skipReconnection = true; if (this.reconnectTimeoutHandle) { clearTimeout(this.reconnectTimeoutHandle); this.reconnectTimeoutHandle = void 0; } if (this.pingIntervalHandle) { clearInterval(this.pingIntervalHandle); this.pingIntervalHandle = void 0; } this.closeAllSubscriptions("relay connection closed by us"); this._connected = false; this.idleSince = void 0; this.onclose?.(); if (this.ws?.readyState === this._WebSocket.OPEN) { this.ws?.close(); } } _onmessage(ev) { const json = ev.data; if (!json) { return; } const subid = getSubscriptionId(json); if (subid) { const so = this.openSubs.get(subid); if (!so) { return; } const id = getHex64(json, "id"); const alreadyHave = so.alreadyHaveEvent?.(id); so.receivedEvent?.(this, id); if (alreadyHave) { return; } } try { let data = JSON.parse(json); switch (data[0]) { case "EVENT": { const so = this.openSubs.get(data[1]); const event = data[2]; if (this.verifyEvent(event) && matchFilters(so.filters, event)) { so.onevent(event); } if (!so.lastEmitted || so.lastEmitted < event.created_at) so.lastEmitted = event.created_at; return; } case "COUNT": { const id = data[1]; const payload = data[2]; const cr = this.openCountRequests.get(id); if (cr) { cr.resolve(payload.count); this.openCountRequests.delete(id); } return; } case "EOSE": { const so = this.openSubs.get(data[1]); if (!so) return; so.receivedEose(); return; } case "OK": { const id = data[1]; const ok = data[2]; const reason = data[3]; const ep = this.openEventPublishes.get(id); if (ep) { clearTimeout(ep.timeout); if (ok) ep.resolve(reason); else ep.reject(new Error(reason)); this.openEventPublishes.delete(id); } return; } case "CLOSED": { const id = data[1]; const so = this.openSubs.get(id); if (!so) return; so.closed = true; so.close(data[2]); return; } case "NOTICE": { this.onnotice(data[1]); return; } case "AUTH": { this.challenge = data[1]; if (this.onauth) { this.auth(this.onauth); } return; } default: { const so = this.openSubs.get(data[1]); so?.oncustom?.(data); return; } } } catch (err) { const [_, __, event] = JSON.parse(json); self.printer.maybe(event.pubkey, ":: caught err", event, this.url, err); return; } } }; var Subscription = class { relay; id; lastEmitted; closed = false; eosed = false; filters; alreadyHaveEvent; receivedEvent; onevent; oneose; onclose; oncustom; eoseTimeout; eoseTimeoutHandle; constructor(relay, id, filters, params) { if (filters.length === 0) throw new Error("subscription can't be created with zero filters"); this.relay = relay; this.filters = filters; this.id = id; this.alreadyHaveEvent = params.alreadyHaveEvent; this.receivedEvent = params.receivedEvent; this.eoseTimeout = params.eoseTimeout || relay.baseEoseTimeout; this.oneose = params.oneose; this.onclose = params.onclose; this.onevent = params.onevent || ((event) => { console.warn( `onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`, event ); }); } fire() { this.relay.send('["REQ","' + this.id + '",' + JSON.stringify(this.filters).substring(1)); this.eoseTimeoutHandle = setTimeout(this.receivedEose.bind(this), this.eoseTimeout); } receivedEose() { if (this.eosed) return; clearTimeout(this.eoseTimeoutHandle); this.eosed = true; this.oneose?.(); } close(reason = "closed by caller") { if (!this.closed && this.relay.connected) { try { this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]"); } catch (err) { if (err instanceof SendingOnClosedConnection) { } else { throw err; } } this.closed = true; } this.relay.openSubs.delete(this.id); this.relay.ongoingOperations--; if (this.relay.ongoingOperations === 0) this.relay.idleSince = Date.now(); this.onclose?.(reason); } }; // relay.ts var _WebSocket; try { _WebSocket = WebSocket; } catch { } var Relay = class extends AbstractRelay { constructor(url, options) { super(url, { verifyEvent, websocketImplementation: _WebSocket, ...options }); } static async connect(url, options) { const relay = new Relay(url, options); await relay.connect(); return relay; } }; // helpers.ts var alwaysTrue = (t) => { t[verifiedSymbol] = true; return true; }; // abstract-pool.ts var AbstractSimplePool = class { relays = /* @__PURE__ */ new Map(); seenOn = /* @__PURE__ */ new Map(); trackRelays = false; verifyEvent; enablePing; enableReconnect; automaticallyAuth; trustedRelayURLs = /* @__PURE__ */ new Set(); onRelayConnectionFailure; onRelayConnectionSuccess; allowConnectingToRelay; maxWaitForConnection; _WebSocket; constructor(opts) { this.verifyEvent = opts.verifyEvent; this._WebSocket = opts.websocketImplementation; this.enablePing = opts.enablePing; this.enableReconnect = opts.enableReconnect || false; this.automaticallyAuth = opts.automaticallyAuth; this.onRelayConnectionFailure = opts.onRelayConnectionFailure; this.onRelayConnectionSuccess = opts.onRelayConnectionSuccess; this.allowConnectingToRelay = opts.allowConnectingToRelay; this.maxWaitForConnection = opts.maxWaitForConnection || 3e3; } async ensureRelay(url, params) { url = normalizeURL(url); let relay = this.relays.get(url); if (!relay) { relay = new AbstractRelay(url, { verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent, websocketImplementation: this._WebSocket, enablePing: this.enablePing, enableReconnect: this.enableReconnect }); relay.onclose = () => { this.relays.delete(url); }; this.relays.set(url, relay); } if (this.automaticallyAuth) { const authSignerFn = this.automaticallyAuth(url); if (authSignerFn) { relay.onauth = authSignerFn; } } try { await relay.connect({ timeout: params?.connectionTimeout, abort: params?.abort }); } catch (err) { this.relays.delete(url); throw err; } return relay; } close(relays) { relays.map(normalizeURL).forEach((url) => { this.relays.get(url)?.close(); this.relays.delete(url); }); } subscribe(relays, filter, params) { const request = []; const uniqUrls = []; for (let i2 = 0; i2 < relays.length; i2++) { const url = normalizeURL(relays[i2]); if (!request.find((r) => r.url === url)) { if (uniqUrls.indexOf(url) === -1) { uniqUrls.push(url); request.push({ url, filter }); } } } return this.subscribeMap(request, params); } subscribeMany(relays, filter, params) { return this.subscribe(relays, filter, params); } subscribeMap(requests, params) { const grouped = /* @__PURE__ */ new Map(); for (const req of requests) { const { url, filter } = req; if (!grouped.has(url)) grouped.set(url, []); grouped.get(url).push(filter); } const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters })); if (this.trackRelays) { params.receivedEvent = (relay, id) => { let set = this.seenOn.get(id); if (!set) { set = /* @__PURE__ */ new Set(); this.seenOn.set(id, set); } set.add(relay); }; } const _knownIds = /* @__PURE__ */ new Set(); const subs = []; const eosesReceived = []; let handleEose = (i2) => { if (eosesReceived[i2]) return; eosesReceived[i2] = true; if (eosesReceived.filter((a) => a).length === groupedRequests.length) { params.oneose?.(); handleEose = () => { }; } }; const closesReceived = []; let handleClose = (i2, reason) => { if (closesReceived[i2]) return; handleEose(i2); closesReceived[i2] = reason; if (closesReceived.filter((a) => a).length === groupedRequests.length) { params.onclose?.(closesReceived); handleClose = () => { }; } }; const localAlreadyHaveEventHandler = (id) => { if (params.alreadyHaveEvent?.(id)) { return true; } const have = _knownIds.has(id); _knownIds.add(id); return have; }; const allOpened = Promise.all( groupedRequests.map(async ({ url, filters }, i2) => { if (this.allowConnectingToRelay?.(url, ["read", filters]) === false) { handleClose(i2, "connection skipped by allowConnectingToRelay"); return; } let relay; try { relay = await this.ensureRelay(url, { connectionTimeout: this.maxWaitForConnection < (params.maxWait || 0) ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : this.maxWaitForConnection, abort: params.abort }); } catch (err) { this.onRelayConnectionFailure?.(url); handleClose(i2, err?.message || String(err)); return; } this.onRelayConnectionSuccess?.(url); let subscription = relay.subscribe(filters, { ...params, oneose: () => handleEose(i2), onclose: (reason) => { if (reason.startsWith("auth-required: ") && params.onauth) { relay.auth(params.onauth).then(() => { relay.subscribe(filters, { ...params, oneose: () => handleEose(i2), onclose: (reason2) => { handleClose(i2, reason2); }, alreadyHaveEvent: localAlreadyHaveEventHandler, eoseTimeout: params.maxWait, abort: params.abort }); }).catch((err) => { handleClose(i2, `auth was required and attempted, but failed with: ${err}`); }); } else { handleClose(i2, reason); } }, alreadyHaveEvent: localAlreadyHaveEventHandler, eoseTimeout: params.maxWait, abort: params.abort }); subs.push(subscription); }) ); return { async close(reason) { await allOpened; subs.forEach((sub) => { sub.close(reason); }); } }; } subscribeEose(relays, filter, params) { let subcloser; subcloser = this.subscribe(relays, filter, { ...params, oneose() { const reason = "closed automatically on eose"; if (subcloser) subcloser.close(reason); else params.onclose?.(relays.map((_) => reason)); } }); return subcloser; } subscribeManyEose(relays, filter, params) { return this.subscribeEose(relays, filter, params); } async querySync(relays, filter, params) { return new Promise(async (resolve) => { const events = []; this.subscribeEose(relays, filter, { ...params, onevent(event) { events.push(event); }, onclose(_) { resolve(events); } }); }); } async get(relays, filter, params) { filter.limit = 1; const events = await this.querySync(relays, filter, params); events.sort((a, b) => b.created_at - a.created_at); return events[0] || null; } publish(relays, event, params) { return relays.map(normalizeURL).map(async (url, i2, arr) => { if (arr.indexOf(url) !== i2) { return Promise.reject("duplicate url"); } if (this.allowConnectingToRelay?.(url, ["write", event]) === false) { return Promise.reject("connection skipped by allowConnectingToRelay"); } let r; try { r = await this.ensureRelay(url, { connectionTimeout: this.maxWaitForConnection < (params?.maxWait || 0) ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : this.maxWaitForConnection, abort: params?.abort }); } catch (err) { this.onRelayConnectionFailure?.(url); return String("connection failure: " + String(err)); } return r.publish(event).catch(async (err) => { if (err instanceof Error && err.message.startsWith("auth-required: ") && params?.onauth) { await r.auth(params.onauth); return r.publish(event); } throw err; }).then((reason) => { if (this.trackRelays) { let set = this.seenOn.get(event.id); if (!set) { set = /* @__PURE__ */ new Set(); this.seenOn.set(event.id, set); } set.add(r); } return reason; }); }); } listConnectionStatus() { const map = /* @__PURE__ */ new Map(); this.relays.forEach((relay, url) => map.set(url, relay.connected)); return map; } destroy() { this.relays.forEach((conn) => conn.close()); this.relays = /* @__PURE__ */ new Map(); } pruneIdleRelays(idleThresholdMs = 1e4) { const prunedUrls = []; for (const [url, relay] of this.relays) { if (relay.idleSince && Date.now() - relay.idleSince >= idleThresholdMs) { this.relays.delete(url); prunedUrls.push(url); relay.close(); } } return prunedUrls; } }; // pool.ts var _WebSocket2; try { _WebSocket2 = WebSocket; } catch { } var SimplePool = class extends AbstractSimplePool { constructor(options) { super({ verifyEvent, websocketImplementation: _WebSocket2, maxWaitForConnection: 3e3, ...options }); } }; // nip19.ts var nip19_exports = {}; __export(nip19_exports, { BECH32_REGEX: () => BECH32_REGEX, Bech32MaxSize: () => Bech32MaxSize, NostrTypeGuard: () => NostrTypeGuard, decode: () => decode, decodeNostrURI: () => decodeNostrURI, encodeBytes: () => encodeBytes, naddrEncode: () => naddrEncode, neventEncode: () => neventEncode, noteEncode: () => noteEncode, nprofileEncode: () => nprofileEncode, npubEncode: () => npubEncode, nsecEncode: () => nsecEncode }); // node_modules/@scure/base/index.js function isBytes2(a) { return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array"; } function abytes2(b) { if (!isBytes2(b)) throw new Error("Uint8Array expected"); } function isArrayOf(isString, arr) { if (!Array.isArray(arr)) return false; if (arr.length === 0) return true; if (isString) { return arr.every((item) => typeof item === "string"); } else { return arr.every((item) => Number.isSafeInteger(item)); } } function afn(input) { if (typeof input !== "function") throw new Error("function expected"); return true; } function astr(label, input) { if (typeof input !== "string") throw new Error(`${label}: string expected`); return true; } function anumber2(n) { if (!Number.isSafeInteger(n)) throw new Error(`invalid integer: ${n}`); } function aArr(input) { if (!Array.isArray(input)) throw new Error("array expected"); } function astrArr(label, input) { if (!isArrayOf(true, input)) throw new Error(`${label}: array of strings expected`); } function anumArr(label, input) { if (!isArrayOf(false, input)) throw new Error(`${label}: array of numbers expected`); } function chain(...args) { const id = (a) => a; const wrap = (a, b) => (c) => a(b(c)); const encode = args.map((x) => x.encode).reduceRight(wrap, id); const decode2 = args.map((x) => x.decode).reduce(wrap, id); return { encode, decode: decode2 }; } function alphabet(letters) { const lettersA = typeof letters === "string" ? letters.split("") : letters; const len = lettersA.length; astrArr("alphabet", lettersA); const indexes = new Map(lettersA.map((l, i2) => [l, i2])); return { encode: (digits) => { aArr(digits); return digits.map((i2) => { if (!Number.isSafeInteger(i2) || i2 < 0 || i2 >= len) throw new Error(`alphabet.encode: digit index outside alphabet "${i2}". Allowed: ${letters}`); return lettersA[i2]; }); }, decode: (input) => { aArr(input); return input.map((letter) => { astr("alphabet.decode", letter); const i2 = indexes.get(letter); if (i2 === void 0) throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`); return i2; }); } }; } function join(separator = "") { astr("join", separator); return { encode: (from) => { astrArr("join.decode", from); return from.join(separator); }, decode: (to) => { astr("join.decode", to); return to.split(separator); } }; } function padding(bits, chr = "=") { anumber2(bits); astr("padding", chr); return { encode(data) { astrArr("padding.encode", data); while (data.length * bits % 8) data.push(chr); return data; }, decode(input) { astrArr("padding.decode", input); let end = input.length; if (end * bits % 8) throw new Error("padding: invalid, string should have whole number of bytes"); for (; end > 0 && input[end - 1] === chr; end--) { const last = end - 1; const byte = last * bits; if (byte % 8 === 0) throw new Error("padding: invalid, string has too much padding"); } return input.slice(0, end); } }; } function normalize(fn) { afn(fn); return { encode: (from) => from, decode: (to) => fn(to) }; } function convertRadix(data, from, to) { if (from < 2) throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`); if (to < 2) throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`); aArr(data); if (!data.length) return []; let pos = 0; const res = []; const digits = Array.from(data, (d) => { anumber2(d); if (d < 0 || d >= from) throw new Error(`invalid integer: ${d}`); return d; }); const dlen = digits.length; while (true) { let carry = 0; let done = true; for (let i2 = pos; i2 < dlen; i2++) { const digit = digits[i2]; const fromCarry = from * carry; const digitBase = fromCarry + digit; if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) { throw new Error("convertRadix: carry overflow"); } const div = digitBase / to; carry = digitBase % to; const rounded = Math.floor(div); digits[i2] = rounded; if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase) throw new Error("convertRadix: carry overflow"); if (!done) continue; else if (!rounded) pos = i2; else done = false; } res.push(carry); if (done) break; } for (let i2 = 0; i2 < data.length - 1 && data[i2] === 0; i2++) res.push(0); return res.reverse(); } var gcd = (a, b) => b === 0 ? a : gcd(b, a % b); var radix2carry = (from, to) => from + (to - gcd(from, to)); var powers = /* @__PURE__ */ (() => { let res = []; for (let i2 = 0; i2 < 40; i2++) res.push(2 ** i2); return res; })(); function convertRadix2(data, from, to, padding2) { aArr(data); if (from <= 0 || from > 32) throw new Error(`convertRadix2: wrong from=${from}`); if (to <= 0 || to > 32) throw new Error(`convertRadix2: wrong to=${to}`); if (radix2carry(from, to) > 32) { throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`); } let carry = 0; let pos = 0; const max = powers[from]; const mask = powers[to] - 1; const res = []; for (const n of data) { anumber2(n); if (n >= max) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`); carry = carry << from | n; if (pos + from > 32) throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`); pos += from; for (; pos >= to; pos -= to) res.push((carry >> pos - to & mask) >>> 0); const pow = powers[pos]; if (pow === void 0) throw new Error("invalid carry"); carry &= pow - 1; } carry = carry << to - pos & mask; if (!padding2 && pos >= from) throw new Error("Excess padding"); if (!padding2 && carry > 0) throw new Error(`Non-zero padding: ${carry}`); if (padding2 && pos > 0) res.push(carry >>> 0); return res; } function radix(num2) { anumber2(num2); const _256 = 2 ** 8; return { encode: (bytes) => { if (!isBytes2(bytes)) throw new Error("radix.encode input should be Uint8Array"); return convertRadix(Array.from(bytes), _256, num2); }, decode: (digits) => { anumArr("radix.decode", digits); return Uint8Array.from(convertRadix(digits, num2, _256)); } }; } function radix2(bits, revPadding = false) { anumber2(bits); if (bits <= 0 || bits > 32) throw new Error("radix2: bits should be in (0..32]"); if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32) throw new Error("radix2: carry overflow"); return { encode: (bytes) => { if (!isBytes2(bytes)) throw new Error("radix2.encode input should be Uint8Array"); return convertRadix2(Array.from(bytes), 8, bits, !revPadding); }, decode: (digits) => { anumArr("radix2.decode", digits); return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding)); } }; } function unsafeWrapper(fn) { afn(fn); return function(...args) { try { return fn.apply(null, args); } catch (e) { } }; } var base16 = chain(radix2(4), alphabet("0123456789ABCDEF"), join("")); var base32 = chain(radix2(5), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"), padding(5), join("")); var base32nopad = chain(radix2(5), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"), join("")); var base32hex = chain(radix2(5), alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUV"), padding(5), join("")); var base32hexnopad = chain(radix2(5), alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUV"), join("")); var base32crockford = chain(radix2(5), alphabet("0123456789ABCDEFGHJKMNPQRSTVWXYZ"), join(""), normalize((s) => s.toUpperCase().replace(/O/g, "0").replace(/[IL]/g, "1"))); var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")(); var decodeBase64Builtin = (s, isUrl) => { astr("base64", s); const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/; const alphabet2 = isUrl ? "base64url" : "base64"; if (s.length > 0 && !re.test(s)) throw new Error("invalid base64"); return Uint8Array.fromBase64(s, { alphabet: alphabet2, lastChunkHandling: "strict" }); }; var base64 = hasBase64Builtin ? { encode(b) { abytes2(b); return b.toBase64(); }, decode(s) { return decodeBase64Builtin(s, false); } } : chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), padding(6), join("")); var base64nopad = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), join("")); var base64url = hasBase64Builtin ? { encode(b) { abytes2(b); return b.toBase64({ alphabet: "base64url" }); }, decode(s) { return decodeBase64Builtin(s, true); } } : chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), padding(6), join("")); var base64urlnopad = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), join("")); var genBase58 = (abc) => chain(radix(58), alphabet(abc), join("")); var base58 = genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); var base58flickr = genBase58("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); var base58xrp = genBase58("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"); var BECH_ALPHABET = chain(alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), join("")); var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059]; function bech32Polymod(pre) { const b = pre >> 25; let chk = (pre & 33554431) << 5; for (let i2 = 0; i2 < POLYMOD_GENERATORS.length; i2++) { if ((b >> i2 & 1) === 1) chk ^= POLYMOD_GENERATORS[i2]; } return chk; } function bechChecksum(prefix, words, encodingConst = 1) { const len = prefix.length; let chk = 1; for (let i2 = 0; i2 < len; i2++) { const c = prefix.charCodeAt(i2); if (c < 33 || c > 126) throw new Error(`Invalid prefix (${prefix})`); chk = bech32Polymod(chk) ^ c >> 5; } chk = bech32Polymod(chk); for (let i2 = 0; i2 < len; i2++) chk = bech32Polymod(chk) ^ prefix.charCodeAt(i2) & 31; for (let v of words) chk = bech32Polymod(chk) ^ v; for (let i2 = 0; i2 < 6; i2++) chk = bech32Polymod(chk); chk ^= encodingConst; return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false)); } function genBech32(encoding) { const ENCODING_CONST = encoding === "bech32" ? 1 : 734539939; const _words = radix2(5); const fromWords = _words.decode; const toWords = _words.encode; const fromWordsUnsafe = unsafeWrapper(fromWords); function encode(prefix, words, limit = 90) { astr("bech32.encode prefix", prefix); if (isBytes2(words)) words = Array.from(words); anumArr("bech32.encode", words); const plen = prefix.length; if (plen === 0) throw new TypeError(`Invalid prefix length ${plen}`); const actualLength = plen + 7 + words.length; if (limit !== false && actualLength > limit) throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`); const lowered = prefix.toLowerCase(); const sum = bechChecksum(lowered, words, ENCODING_CONST); return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`; } function decode2(str, limit = 90) { astr("bech32.decode input", str); const slen = str.length; if (slen < 8 || limit !== false && slen > limit) throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`); const lowered = str.toLowerCase(); if (str !== lowered && str !== str.toUpperCase()) throw new Error(`String must be lowercase or uppercase`); const sepIndex = lowered.lastIndexOf("1"); if (sepIndex === 0 || sepIndex === -1) throw new Error(`Letter "1" must be present between prefix and data only`); const prefix = lowered.slice(0, sepIndex); const data = lowered.slice(sepIndex + 1); if (data.length < 6) throw new Error("Data must be at least 6 characters long"); const words = BECH_ALPHABET.decode(data).slice(0, -6); const sum = bechChecksum(prefix, words, ENCODING_CONST); if (!data.endsWith(sum)) throw new Error(`Invalid checksum in ${str}: expected "${sum}"`); return { prefix, words }; } const decodeUnsafe = unsafeWrapper(decode2); function decodeToBytes(str) { const { prefix, words } = decode2(str, false); return { prefix, words, bytes: fromWords(words) }; } function encodeFromBytes(prefix, bytes) { return encode(prefix, toWords(bytes)); } return { encode, decode: decode2, encodeFromBytes, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords }; } var bech32 = genBech32("bech32"); var bech32m = genBech32("bech32m"); var hasHexBuiltin2 = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")(); var hexBuiltin = { encode(data) { abytes2(data); return data.toHex(); }, decode(s) { astr("hex", s); return Uint8Array.fromHex(s); } }; var hex = hasHexBuiltin2 ? hexBuiltin : chain(radix2(4), alphabet("0123456789abcdef"), join(""), normalize((s) => { if (typeof s !== "string" || s.length % 2 !== 0) throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`); return s.toLowerCase(); })); // nip19.ts var NostrTypeGuard = { isNProfile: (value) => /^nprofile1[a-z\d]+$/.test(value || ""), isNEvent: (value) => /^nevent1[a-z\d]+$/.test(value || ""), isNAddr: (value) => /^naddr1[a-z\d]+$/.test(value || ""), isNSec: (value) => /^nsec1[a-z\d]{58}$/.test(value || ""), isNPub: (value) => /^npub1[a-z\d]{58}$/.test(value || ""), isNote: (value) => /^note1[a-z\d]+$/.test(value || ""), isNcryptsec: (value) => /^ncryptsec1[a-z\d]+$/.test(value || "") }; var Bech32MaxSize = 5e3; var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/; function integerToUint8Array(number) { const uint8Array = new Uint8Array(4); uint8Array[0] = number >> 24 & 255; uint8Array[1] = number >> 16 & 255; uint8Array[2] = number >> 8 & 255; uint8Array[3] = number & 255; return uint8Array; } function decodeNostrURI(nip19code) { try { if (nip19code.startsWith("nostr:")) nip19code = nip19code.substring(6); return decode(nip19code); } catch (_err) { return { type: "invalid", data: null }; } } function decode(code) { let { prefix, words } = bech32.decode(code, Bech32MaxSize); let data = new Uint8Array(bech32.fromWords(words)); switch (prefix) { case "nprofile": { let tlv = parseTLV(data); if (!tlv[0]?.[0]) throw new Error("missing TLV 0 for nprofile"); if (tlv[0][0].length !== 32) throw new Error("TLV 0 should be 32 bytes"); return { type: "nprofile", data: { pubkey: bytesToHex(tlv[0][0]), relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [] } }; } case "nevent": { let tlv = parseTLV(data); if (!tlv[0]?.[0]) throw new Error("missing TLV 0 for nevent"); if (tlv[0][0].length !== 32) throw new Error("TLV 0 should be 32 bytes"); if (tlv[2] && tlv[2][0].length !== 32) throw new Error("TLV 2 should be 32 bytes"); if (tlv[3] && tlv[3][0].length !== 4) throw new Error("TLV 3 should be 4 bytes"); return { type: "nevent", data: { id: bytesToHex(tlv[0][0]), relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [], author: tlv[2]?.[0] ? bytesToHex(tlv[2][0]) : void 0, kind: tlv[3]?.[0] ? parseInt(bytesToHex(tlv[3][0]), 16) : void 0 } }; } case "naddr": { let tlv = parseTLV(data); if (!tlv[0]?.[0]) throw new Error("missing TLV 0 for naddr"); if (!tlv[2]?.[0]) throw new Error("missing TLV 2 for naddr"); if (tlv[2][0].length !== 32) throw new Error("TLV 2 should be 32 bytes"); if (!tlv[3]?.[0]) throw new Error("missing TLV 3 for naddr"); if (tlv[3][0].length !== 4) throw new Error("TLV 3 should be 4 bytes"); return { type: "naddr", data: { identifier: utf8Decoder.decode(tlv[0][0]), pubkey: bytesToHex(tlv[2][0]), kind: parseInt(bytesToHex(tlv[3][0]), 16), relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [] } }; } case "nsec": return { type: prefix, data }; case "npub": case "note": return { type: prefix, data: bytesToHex(data) }; default: throw new Error(`unknown prefix ${prefix}`); } } function parseTLV(data) { let result = {}; let rest = data; while (rest.length > 0) { let t = rest[0]; let l = rest[1]; let v = rest.slice(2, 2 + l); rest = rest.slice(2 + l); if (v.length < l) throw new Error(`not enough data to read on TLV ${t}`); result[t] = result[t] || []; result[t].push(v); } return result; } function nsecEncode(key) { return encodeBytes("nsec", key); } function npubEncode(hex2) { return encodeBytes("npub", hexToBytes(hex2)); } function noteEncode(hex2) { return encodeBytes("note", hexToBytes(hex2)); } function encodeBech32(prefix, data) { let words = bech32.toWords(data); return bech32.encode(prefix, words, Bech32MaxSize); } function encodeBytes(prefix, bytes) { return encodeBech32(prefix, bytes); } function nprofileEncode(profile) { let data = encodeTLV({ 0: [hexToBytes(profile.pubkey)], 1: (profile.relays || []).map((url) => utf8Encoder.encode(url)) }); return encodeBech32("nprofile", data); } function neventEncode(event) { let kindArray; if (event.kind !== void 0) { kindArray = integerToUint8Array(event.kind); } let data = encodeTLV({ 0: [hexToBytes(event.id)], 1: (event.relays || []).map((url) => utf8Encoder.encode(url)), 2: event.author ? [hexToBytes(event.author)] : [], 3: kindArray ? [new Uint8Array(kindArray)] : [] }); return encodeBech32("nevent", data); } function naddrEncode(addr) { let kind = new ArrayBuffer(4); new DataView(kind).setUint32(0, addr.kind, false); let data = encodeTLV({ 0: [utf8Encoder.encode(addr.identifier)], 1: (addr.relays || []).map((url) => utf8Encoder.encode(url)), 2: [hexToBytes(addr.pubkey)], 3: [new Uint8Array(kind)] }); return encodeBech32("naddr", data); } function encodeTLV(tlv) { let entries = []; Object.entries(tlv).reverse().forEach(([t, vs]) => { vs.forEach((v) => { let entry = new Uint8Array(v.length + 2); entry.set([parseInt(t)], 0); entry.set([v.length], 1); entry.set(v, 2); entries.push(entry); }); }); return concatBytes(...entries); } // references.ts var mentionRegex = /\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g; function parseReferences(evt) { let references = []; for (let ref of evt.content.matchAll(mentionRegex)) { if (ref[2]) { try { let { type, data } = decode(ref[1]); switch (type) { case "npub": { references.push({ text: ref[0], profile: { pubkey: data, relays: [] } }); break; } case "nprofile": { references.push({ text: ref[0], profile: data }); break; } case "note": { references.push({ text: ref[0], event: { id: data, relays: [] } }); break; } case "nevent": { references.push({ text: ref[0], event: data }); break; } case "naddr": { references.push({ text: ref[0], address: data }); break; } } } catch (err) { } } else if (ref[3]) { let idx = parseInt(ref[3], 10); let tag = evt.tags[idx]; if (!tag) continue; switch (tag[0]) { case "p": { references.push({ text: ref[0], profile: { pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] } }); break; } case "e": { references.push({ text: ref[0], event: { id: tag[1], relays: tag[2] ? [tag[2]] : [] } }); break; } case "a": { try { let [kind, pubkey, identifier] = tag[1].split(":"); references.push({ text: ref[0], address: { identifier, pubkey, kind: parseInt(kind, 10), relays: tag[2] ? [tag[2]] : [] } }); } catch (err) { } break; } } } } return references; } // nip04.ts var nip04_exports = {}; __export(nip04_exports, { decrypt: () => decrypt2, encrypt: () => encrypt2 }); // node_modules/@noble/ciphers/utils.js function isBytes3(a) { return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array"; } function abool2(b) { if (typeof b !== "boolean") throw new Error(`boolean expected, not ${b}`); } function anumber3(n) { if (!Number.isSafeInteger(n) || n < 0) throw new Error("positive integer expected, got " + n); } function abytes3(value, length, title = "") { const bytes = isBytes3(value); const len = value?.length; const needsLen = length !== void 0; if (!bytes || needsLen && len !== length) { const prefix = title && `"${title}" `; const ofLen = needsLen ? ` of length ${length}` : ""; const got = bytes ? `length=${len}` : `type=${typeof value}`; throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got); } return value; } function aexists2(instance, checkFinished = true) { if (instance.destroyed) throw new Error("Hash instance has been destroyed"); if (checkFinished && instance.finished) throw new Error("Hash#digest() has already been called"); } function aoutput2(out, instance) { abytes3(out, void 0, "output"); const min = instance.outputLen; if (out.length < min) { throw new Error("digestInto() expects output buffer of length at least " + min); } } function u32(arr) { return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); } function clean2(...arrays) { for (let i2 = 0; i2 < arrays.length; i2++) { arrays[i2].fill(0); } } function createView2(arr) { return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); } var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)(); function overlapBytes(a, b) { return a.buffer === b.buffer && a.byteOffset < b.byteOffset + b.byteLength && b.byteOffset < a.byteOffset + a.byteLength; } function complexOverlapBytes(input, output) { if (overlapBytes(input, output) && input.byteOffset < output.byteOffset) throw new Error("complex overlap of input and output is not supported"); } function checkOpts(defaults, opts) { if (opts == null || typeof opts !== "object") throw new Error("options must be defined"); const merged = Object.assign(defaults, opts); return merged; } function equalBytes(a, b) { if (a.length !== b.length) return false; let diff = 0; for (let i2 = 0; i2 < a.length; i2++) diff |= a[i2] ^ b[i2]; return diff === 0; } var wrapCipher = (params, constructor) => { function wrappedCipher(key, ...args) { abytes3(key, void 0, "key"); if (!isLE) throw new Error("Non little-endian hardware is not yet supported"); if (params.nonceLength !== void 0) { const nonce = args[0]; abytes3(nonce, params.varSizeNonce ? void 0 : params.nonceLength, "nonce"); } const tagl = params.tagLength; if (tagl && args[1] !== void 0) abytes3(args[1], void 0, "AAD"); const cipher = constructor(key, ...args); const checkOutput = (fnLength, output) => { if (output !== void 0) { if (fnLength !== 2) throw new Error("cipher output not supported"); abytes3(output, void 0, "output"); } }; let called = false; const wrCipher = { encrypt(data, output) { if (called) throw new Error("cannot encrypt() twice with same key + nonce"); called = true; abytes3(data); checkOutput(cipher.encrypt.length, output); return cipher.encrypt(data, output); }, decrypt(data, output) { abytes3(data); if (tagl && data.length < tagl) throw new Error('"ciphertext" expected length bigger than tagLength=' + tagl); checkOutput(cipher.decrypt.length, output); return cipher.decrypt(data, output); } }; return wrCipher; } Object.assign(wrappedCipher, params); return wrappedCipher; }; function getOutput(expectedLength, out, onlyAligned = true) { if (out === void 0) return new Uint8Array(expectedLength); if (out.length !== expectedLength) throw new Error('"output" expected Uint8Array of length ' + expectedLength + ", got: " + out.length); if (onlyAligned && !isAligned32(out)) throw new Error("invalid output, must be aligned"); return out; } function u64Lengths(dataLength, aadLength, isLE2) { abool2(isLE2); const num2 = new Uint8Array(16); const view = createView2(num2); view.setBigUint64(0, BigInt(aadLength), isLE2); view.setBigUint64(8, BigInt(dataLength), isLE2); return num2; } function isAligned32(bytes) { return bytes.byteOffset % 4 === 0; } function copyBytes2(bytes) { return Uint8Array.from(bytes); } // node_modules/@noble/ciphers/aes.js var BLOCK_SIZE = 16; var POLY = 283; function validateKeyLength(key) { if (![16, 24, 32].includes(key.length)) throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + key.length); } function mul2(n) { return n << 1 ^ POLY & -(n >> 7); } function mul(a, b) { let res = 0; for (; b > 0; b >>= 1) { res ^= a & -(b & 1); a = mul2(a); } return res; } var sbox = /* @__PURE__ */ (() => { const t = new Uint8Array(256); for (let i2 = 0, x = 1; i2 < 256; i2++, x ^= mul2(x)) t[i2] = x; const box = new Uint8Array(256); box[0] = 99; for (let i2 = 0; i2 < 255; i2++) { let x = t[255 - i2]; x |= x << 8; box[t[i2]] = (x ^ x >> 4 ^ x >> 5 ^ x >> 6 ^ x >> 7 ^ 99) & 255; } clean2(t); return box; })(); var invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j)); var rotr32_8 = (n) => n << 24 | n >>> 8; var rotl32_8 = (n) => n << 8 | n >>> 24; function genTtable(sbox2, fn) { if (sbox2.length !== 256) throw new Error("Wrong sbox length"); const T0 = new Uint32Array(256).map((_, j) => fn(sbox2[j])); const T1 = T0.map(rotl32_8); const T2 = T1.map(rotl32_8); const T3 = T2.map(rotl32_8); const T01 = new Uint32Array(256 * 256); const T23 = new Uint32Array(256 * 256); const sbox22 = new Uint16Array(256 * 256); for (let i2 = 0; i2 < 256; i2++) { for (let j = 0; j < 256; j++) { const idx = i2 * 256 + j; T01[idx] = T0[i2] ^ T1[j]; T23[idx] = T2[i2] ^ T3[j]; sbox22[idx] = sbox2[i2] << 8 | sbox2[j]; } } return { sbox: sbox2, sbox2: sbox22, T0, T1, T2, T3, T01, T23 }; } var tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => mul(s, 3) << 24 | s << 16 | s << 8 | mul(s, 2)); var tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => mul(s, 11) << 24 | mul(s, 13) << 16 | mul(s, 9) << 8 | mul(s, 14)); var xPowers = /* @__PURE__ */ (() => { const p = new Uint8Array(16); for (let i2 = 0, x = 1; i2 < 16; i2++, x = mul2(x)) p[i2] = x; return p; })(); function expandKeyLE(key) { abytes3(key); const len = key.length; validateKeyLength(key); const { sbox2 } = tableEncoding; const toClean = []; if (!isAligned32(key)) toClean.push(key = copyBytes2(key)); const k32 = u32(key); const Nk = k32.length; const subByte = (n) => applySbox(sbox2, n, n, n, n); const xk = new Uint32Array(len + 28); xk.set(k32); for (let i2 = Nk; i2 < xk.length; i2++) { let t = xk[i2 - 1]; if (i2 % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i2 / Nk - 1]; else if (Nk > 6 && i2 % Nk === 4) t = subByte(t); xk[i2] = xk[i2 - Nk] ^ t; } clean2(...toClean); return xk; } function expandKeyDecLE(key) { const encKey = expandKeyLE(key); const xk = encKey.slice(); const Nk = encKey.length; const { sbox2 } = tableEncoding; const { T0, T1, T2, T3 } = tableDecoding; for (let i2 = 0; i2 < Nk; i2 += 4) { for (let j = 0; j < 4; j++) xk[i2 + j] = encKey[Nk - i2 - 4 + j]; } clean2(encKey); for (let i2 = 4; i2 < Nk - 4; i2++) { const x = xk[i2]; const w = applySbox(sbox2, x, x, x, x); xk[i2] = T0[w & 255] ^ T1[w >>> 8 & 255] ^ T2[w >>> 16 & 255] ^ T3[w >>> 24]; } return xk; } function apply0123(T01, T23, s0, s1, s2, s3) { return T01[s0 << 8 & 65280 | s1 >>> 8 & 255] ^ T23[s2 >>> 8 & 65280 | s3 >>> 24 & 255]; } function applySbox(sbox2, s0, s1, s2, s3) { return sbox2[s0 & 255 | s1 & 65280] | sbox2[s2 >>> 16 & 255 | s3 >>> 16 & 65280] << 16; } function encrypt(xk, s0, s1, s2, s3) { const { sbox2, T01, T23 } = tableEncoding; let k = 0; s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++]; const rounds = xk.length / 4 - 2; for (let i2 = 0; i2 < rounds; i2++) { const t02 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3); const t12 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0); const t22 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1); const t32 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2); s0 = t02, s1 = t12, s2 = t22, s3 = t32; } const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3); const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0); const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1); const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2); return { s0: t0, s1: t1, s2: t2, s3: t3 }; } function decrypt(xk, s0, s1, s2, s3) { const { sbox2, T01, T23 } = tableDecoding; let k = 0; s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++]; const rounds = xk.length / 4 - 2; for (let i2 = 0; i2 < rounds; i2++) { const t02 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1); const t12 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2); const t22 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3); const t32 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0); s0 = t02, s1 = t12, s2 = t22, s3 = t32; } const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1); const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2); const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3); const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0); return { s0: t0, s1: t1, s2: t2, s3: t3 }; } function validateBlockDecrypt(data) { abytes3(data); if (data.length % BLOCK_SIZE !== 0) { throw new Error("aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size " + BLOCK_SIZE); } } function validateBlockEncrypt(plaintext, pcks5, dst) { abytes3(plaintext); let outLen = plaintext.length; const remaining = outLen % BLOCK_SIZE; if (!pcks5 && remaining !== 0) throw new Error("aec/(cbc-ecb): unpadded plaintext with disabled padding"); if (!isAligned32(plaintext)) plaintext = copyBytes2(plaintext); const b = u32(plaintext); if (pcks5) { let left = BLOCK_SIZE - remaining; if (!left) left = BLOCK_SIZE; outLen = outLen + left; } dst = getOutput(outLen, dst); complexOverlapBytes(plaintext, dst); const o = u32(dst); return { b, o, out: dst }; } function validatePCKS(data, pcks5) { if (!pcks5) return data; const len = data.length; if (!len) throw new Error("aes/pcks5: empty ciphertext not allowed"); const lastByte = data[len - 1]; if (lastByte <= 0 || lastByte > 16) throw new Error("aes/pcks5: wrong padding"); const out = data.subarray(0, -lastByte); for (let i2 = 0; i2 < lastByte; i2++) if (data[len - i2 - 1] !== lastByte) throw new Error("aes/pcks5: wrong padding"); return out; } function padPCKS(left) { const tmp = new Uint8Array(16); const tmp32 = u32(tmp); tmp.set(left); const paddingByte = BLOCK_SIZE - left.length; for (let i2 = BLOCK_SIZE - paddingByte; i2 < BLOCK_SIZE; i2++) tmp[i2] = paddingByte; return tmp32; } var cbc = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 16 }, function aescbc(key, iv, opts = {}) { const pcks5 = !opts.disablePadding; return { encrypt(plaintext, dst) { const xk = expandKeyLE(key); const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst); let _iv = iv; const toClean = [xk]; if (!isAligned32(_iv)) toClean.push(_iv = copyBytes2(_iv)); const n32 = u32(_iv); let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; let i2 = 0; for (; i2 + 4 <= b.length; ) { s0 ^= b[i2 + 0], s1 ^= b[i2 + 1], s2 ^= b[i2 + 2], s3 ^= b[i2 + 3]; ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); o[i2++] = s0, o[i2++] = s1, o[i2++] = s2, o[i2++] = s3; } if (pcks5) { const tmp32 = padPCKS(plaintext.subarray(i2 * 4)); s0 ^= tmp32[0], s1 ^= tmp32[1], s2 ^= tmp32[2], s3 ^= tmp32[3]; ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); o[i2++] = s0, o[i2++] = s1, o[i2++] = s2, o[i2++] = s3; } clean2(...toClean); return _out; }, decrypt(ciphertext, dst) { validateBlockDecrypt(ciphertext); const xk = expandKeyDecLE(key); let _iv = iv; const toClean = [xk]; if (!isAligned32(_iv)) toClean.push(_iv = copyBytes2(_iv)); const n32 = u32(_iv); dst = getOutput(ciphertext.length, dst); if (!isAligned32(ciphertext)) toClean.push(ciphertext = copyBytes2(ciphertext)); complexOverlapBytes(ciphertext, dst); const b = u32(ciphertext); const o = u32(dst); let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; for (let i2 = 0; i2 + 4 <= b.length; ) { const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3; s0 = b[i2 + 0], s1 = b[i2 + 1], s2 = b[i2 + 2], s3 = b[i2 + 3]; const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3); o[i2++] = o0 ^ ps0, o[i2++] = o1 ^ ps1, o[i2++] = o2 ^ ps2, o[i2++] = o3 ^ ps3; } clean2(...toClean); return validatePCKS(dst, pcks5); } }; }); function isBytes32(a) { return a instanceof Uint32Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint32Array"; } function encryptBlock(xk, block) { abytes3(block, 16, "block"); if (!isBytes32(xk)) throw new Error("_encryptBlock accepts result of expandKeyLE"); const b32 = u32(block); let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]); b32[0] = s0, b32[1] = s1, b32[2] = s2, b32[3] = s3; return block; } function dbl(block) { let carry = 0; for (let i2 = BLOCK_SIZE - 1; i2 >= 0; i2--) { const newCarry = (block[i2] & 128) >>> 7; block[i2] = block[i2] << 1 | carry; carry = newCarry; } if (carry) { block[BLOCK_SIZE - 1] ^= 135; } return block; } function xorBlock(a, b) { if (a.length !== b.length) throw new Error("xorBlock: blocks must have same length"); for (let i2 = 0; i2 < a.length; i2++) { a[i2] = a[i2] ^ b[i2]; } return a; } var _CMAC = class { buffer; destroyed; k1; k2; xk; constructor(key) { abytes3(key); validateKeyLength(key); this.xk = expandKeyLE(key); this.buffer = new Uint8Array(0); this.destroyed = false; const L = new Uint8Array(BLOCK_SIZE); encryptBlock(this.xk, L); this.k1 = dbl(L); this.k2 = dbl(new Uint8Array(this.k1)); } update(data) { const { destroyed, buffer } = this; if (destroyed) throw new Error("CMAC instance was destroyed"); abytes3(data); const newBuffer = new Uint8Array(buffer.length + data.length); newBuffer.set(buffer); newBuffer.set(data, buffer.length); this.buffer = newBuffer; return this; } digest() { if (this.destroyed) throw new Error("CMAC instance was destroyed"); const { buffer } = this; const msgLen = buffer.length; let n = Math.ceil(msgLen / BLOCK_SIZE); let flag; if (n === 0) { n = 1; flag = false; } else { flag = msgLen % BLOCK_SIZE === 0; } const lastBlockStart = (n - 1) * BLOCK_SIZE; const lastBlockData = buffer.subarray(lastBlockStart); let m_last; if (flag) { m_last = xorBlock(new Uint8Array(lastBlockData), this.k1); } else { const padded = new Uint8Array(BLOCK_SIZE); padded.set(lastBlockData); padded[lastBlockData.length] = 128; m_last = xorBlock(padded, this.k2); } let x = new Uint8Array(BLOCK_SIZE); for (let i2 = 0; i2 < n - 1; i2++) { const m_i = buffer.subarray(i2 * BLOCK_SIZE, (i2 + 1) * BLOCK_SIZE); xorBlock(x, m_i); encryptBlock(this.xk, x); } xorBlock(x, m_last); encryptBlock(this.xk, x); clean2(m_last); return x; } destroy() { const { buffer, destroyed, xk, k1, k2 } = this; if (destroyed) return; this.destroyed = true; clean2(buffer, xk, k1, k2); } }; var cmac = (key, message) => new _CMAC(key).update(message).digest(); cmac.create = (key) => new _CMAC(key); // nip04.ts function encrypt2(secretKey, pubkey, text) { const privkey = secretKey instanceof Uint8Array ? secretKey : hexToBytes(secretKey); const key = secp256k1.getSharedSecret(privkey, hexToBytes("02" + pubkey)); const normalizedKey = getNormalizedX(key); let iv = Uint8Array.from(randomBytes(16)); let plaintext = utf8Encoder.encode(text); let ciphertext = cbc(normalizedKey, iv).encrypt(plaintext); let ctb64 = base64.encode(new Uint8Array(ciphertext)); let ivb64 = base64.encode(new Uint8Array(iv.buffer)); return `${ctb64}?iv=${ivb64}`; } function decrypt2(secretKey, pubkey, data) { const privkey = secretKey instanceof Uint8Array ? secretKey : hexToBytes(secretKey); let [ctb64, ivb64] = data.split("?iv="); let key = secp256k1.getSharedSecret(privkey, hexToBytes("02" + pubkey)); let normalizedKey = getNormalizedX(key); let iv = base64.decode(ivb64); let ciphertext = base64.decode(ctb64); let plaintext = cbc(normalizedKey, iv).decrypt(ciphertext); return utf8Decoder.decode(plaintext); } function getNormalizedX(key) { return key.slice(1, 33); } // nip05.ts var nip05_exports = {}; __export(nip05_exports, { NIP05_REGEX: () => NIP05_REGEX, isNip05: () => isNip05, isValid: () => isValid, queryProfile: () => queryProfile, searchDomain: () => searchDomain, useFetchImplementation: () => useFetchImplementation }); var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/; var isNip05 = (value) => NIP05_REGEX.test(value || ""); var _fetch; try { _fetch = fetch; } catch (_) { null; } function useFetchImplementation(fetchImplementation) { _fetch = fetchImplementation; } async function searchDomain(domain, query = "") { try { const url = `https://${domain}/.well-known/nostr.json?name=${query}`; const res = await _fetch(url, { redirect: "manual" }); if (res.status !== 200) { throw Error("Wrong response code"); } const json = await res.json(); return json.names; } catch (_) { return {}; } } async function queryProfile(fullname) { const match = fullname.match(NIP05_REGEX); if (!match) return null; const [, name = "_", domain] = match; try { const url = `https://${domain}/.well-known/nostr.json?name=${name}`; const res = await _fetch(url, { redirect: "manual" }); if (res.status !== 200) { throw Error("Wrong response code"); } const json = await res.json(); const pubkey = json.names[name]; return pubkey ? { pubkey, relays: json.relays?.[pubkey] } : null; } catch (_e) { return null; } } async function isValid(pubkey, nip05) { const res = await queryProfile(nip05); return res ? res.pubkey === pubkey : false; } // nip10.ts var nip10_exports = {}; __export(nip10_exports, { parse: () => parse }); function parse(event) { const result = { reply: void 0, root: void 0, mentions: [], profiles: [], quotes: [] }; let maybeParent; let maybeRoot; for (let i2 = event.tags.length - 1; i2 >= 0; i2--) { const tag = event.tags[i2]; if (tag[0] === "e" && tag[1]) { const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag; const eventPointer = { id: eTagEventId, relays: eTagRelayUrl ? [eTagRelayUrl] : [], author: eTagAuthor }; if (eTagMarker === "root") { result.root = eventPointer; continue; } if (eTagMarker === "reply") { result.reply = eventPointer; continue; } if (eTagMarker === "mention") { result.mentions.push(eventPointer); continue; } if (!maybeParent) { maybeParent = eventPointer; } else { maybeRoot = eventPointer; } result.mentions.push(eventPointer); continue; } if (tag[0] === "q" && tag[1]) { const [_, eTagEventId, eTagRelayUrl] = tag; result.quotes.push({ id: eTagEventId, relays: eTagRelayUrl ? [eTagRelayUrl] : [] }); } if (tag[0] === "p" && tag[1]) { result.profiles.push({ pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] }); continue; } } if (!result.root) { result.root = maybeRoot || maybeParent || result.reply; } if (!result.reply) { result.reply = maybeParent || result.root; } ; [result.reply, result.root].forEach((ref) => { if (!ref) return; let idx = result.mentions.indexOf(ref); if (idx !== -1) { result.mentions.splice(idx, 1); } if (ref.author) { let author = result.profiles.find((p) => p.pubkey === ref.author); if (author && author.relays) { if (!ref.relays) { ref.relays = []; } author.relays.forEach((url) => { if (ref.relays?.indexOf(url) === -1) ref.relays.push(url); }); author.relays = ref.relays; } } }); result.mentions.forEach((ref) => { if (ref.author) { let author = result.profiles.find((p) => p.pubkey === ref.author); if (author && author.relays) { if (!ref.relays) { ref.relays = []; } author.relays.forEach((url) => { if (ref.relays.indexOf(url) === -1) ref.relays.push(url); }); author.relays = ref.relays; } } }); return result; } // nip11.ts var nip11_exports = {}; __export(nip11_exports, { fetchRelayInformation: () => fetchRelayInformation, useFetchImplementation: () => useFetchImplementation2 }); var _fetch2; try { _fetch2 = fetch; } catch { } function useFetchImplementation2(fetchImplementation) { _fetch2 = fetchImplementation; } async function fetchRelayInformation(url) { return await (await fetch(url.replace("ws://", "http://").replace("wss://", "https://"), { headers: { Accept: "application/nostr+json" } })).json(); } // nip13.ts var nip13_exports = {}; __export(nip13_exports, { getPow: () => getPow, minePow: () => minePow }); function getPow(hex2) { let count = 0; for (let i2 = 0; i2 < 64; i2 += 8) { const nibble = parseInt(hex2.substring(i2, i2 + 8), 16); if (nibble === 0) { count += 32; } else { count += Math.clz32(nibble); break; } } return count; } function getPowFromBytes(hash) { let count = 0; for (let i2 = 0; i2 < hash.length; i2++) { const byte = hash[i2]; if (byte === 0) { count += 8; } else { count += Math.clz32(byte) - 24; break; } } return count; } function minePow(unsigned, difficulty) { let count = 0; const event = unsigned; const tag = ["nonce", count.toString(), difficulty.toString()]; event.tags.push(tag); while (true) { const now2 = Math.floor(new Date().getTime() / 1e3); if (now2 !== event.created_at) { count = 0; event.created_at = now2; } tag[1] = (++count).toString(); const hash = sha256( utf8Encoder.encode(JSON.stringify([0, event.pubkey, event.created_at, event.kind, event.tags, event.content])) ); if (getPowFromBytes(hash) >= difficulty) { event.id = bytesToHex(hash); break; } } return event; } // nip17.ts var nip17_exports = {}; __export(nip17_exports, { unwrapEvent: () => unwrapEvent2, unwrapManyEvents: () => unwrapManyEvents2, wrapEvent: () => wrapEvent2, wrapManyEvents: () => wrapManyEvents2 }); // nip59.ts var nip59_exports = {}; __export(nip59_exports, { createRumor: () => createRumor, createSeal: () => createSeal, createWrap: () => createWrap, unwrapEvent: () => unwrapEvent, unwrapManyEvents: () => unwrapManyEvents, wrapEvent: () => wrapEvent, wrapManyEvents: () => wrapManyEvents }); // nip44.ts var nip44_exports = {}; __export(nip44_exports, { decrypt: () => decrypt3, encrypt: () => encrypt3, getConversationKey: () => getConversationKey, v2: () => v2 }); // node_modules/@noble/ciphers/_arx.js var encodeStr = (str) => Uint8Array.from(str.split(""), (c) => c.charCodeAt(0)); var sigma16 = encodeStr("expand 16-byte k"); var sigma32 = encodeStr("expand 32-byte k"); var sigma16_32 = u32(sigma16); var sigma32_32 = u32(sigma32); function rotl(a, b) { return a << b | a >>> 32 - b; } function isAligned322(b) { return b.byteOffset % 4 === 0; } var BLOCK_LEN = 64; var BLOCK_LEN32 = 16; var MAX_COUNTER = 2 ** 32 - 1; var U32_EMPTY = Uint32Array.of(); function runCipher(core, sigma, key, nonce, data, output, counter, rounds) { const len = data.length; const block = new Uint8Array(BLOCK_LEN); const b32 = u32(block); const isAligned = isAligned322(data) && isAligned322(output); const d32 = isAligned ? u32(data) : U32_EMPTY; const o32 = isAligned ? u32(output) : U32_EMPTY; for (let pos = 0; pos < len; counter++) { core(sigma, key, nonce, b32, counter, rounds); if (counter >= MAX_COUNTER) throw new Error("arx: counter overflow"); const take = Math.min(BLOCK_LEN, len - pos); if (isAligned && take === BLOCK_LEN) { const pos32 = pos / 4; if (pos % 4 !== 0) throw new Error("arx: invalid block position"); for (let j = 0, posj; j < BLOCK_LEN32; j++) { posj = pos32 + j; o32[posj] = d32[posj] ^ b32[j]; } pos += BLOCK_LEN; continue; } for (let j = 0, posj; j < take; j++) { posj = pos + j; output[posj] = data[posj] ^ block[j]; } pos += take; } } function createCipher(core, opts) { const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts); if (typeof core !== "function") throw new Error("core must be a function"); anumber3(counterLength); anumber3(rounds); abool2(counterRight); abool2(allowShortKeys); return (key, nonce, data, output, counter = 0) => { abytes3(key, void 0, "key"); abytes3(nonce, void 0, "nonce"); abytes3(data, void 0, "data"); const len = data.length; if (output === void 0) output = new Uint8Array(len); abytes3(output, void 0, "output"); anumber3(counter); if (counter < 0 || counter >= MAX_COUNTER) throw new Error("arx: counter overflow"); if (output.length < len) throw new Error(`arx: output (${output.length}) is shorter than data (${len})`); const toClean = []; let l = key.length; let k; let sigma; if (l === 32) { toClean.push(k = copyBytes2(key)); sigma = sigma32_32; } else if (l === 16 && allowShortKeys) { k = new Uint8Array(32); k.set(key); k.set(key, 16); sigma = sigma16_32; toClean.push(k); } else { abytes3(key, 32, "arx key"); throw new Error("invalid key size"); } if (!isAligned322(nonce)) toClean.push(nonce = copyBytes2(nonce)); const k32 = u32(k); if (extendNonceFn) { if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`); extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32); nonce = nonce.subarray(16); } const nonceNcLen = 16 - counterLength; if (nonceNcLen !== nonce.length) throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`); if (nonceNcLen !== 12) { const nc = new Uint8Array(12); nc.set(nonce, counterRight ? 0 : 12 - nonce.length); nonce = nc; toClean.push(nonce); } const n32 = u32(nonce); runCipher(core, sigma, k32, n32, data, output, counter, rounds); clean2(...toClean); return output; }; } // node_modules/@noble/ciphers/_poly1305.js function u8to16(a, i2) { return a[i2++] & 255 | (a[i2++] & 255) << 8; } var Poly1305 = class { blockLen = 16; outputLen = 16; buffer = new Uint8Array(16); r = new Uint16Array(10); h = new Uint16Array(10); pad = new Uint16Array(8); pos = 0; finished = false; constructor(key) { key = copyBytes2(abytes3(key, 32, "key")); const t0 = u8to16(key, 0); const t1 = u8to16(key, 2); const t2 = u8to16(key, 4); const t3 = u8to16(key, 6); const t4 = u8to16(key, 8); const t5 = u8to16(key, 10); const t6 = u8to16(key, 12); const t7 = u8to16(key, 14); this.r[0] = t0 & 8191; this.r[1] = (t0 >>> 13 | t1 << 3) & 8191; this.r[2] = (t1 >>> 10 | t2 << 6) & 7939; this.r[3] = (t2 >>> 7 | t3 << 9) & 8191; this.r[4] = (t3 >>> 4 | t4 << 12) & 255; this.r[5] = t4 >>> 1 & 8190; this.r[6] = (t4 >>> 14 | t5 << 2) & 8191; this.r[7] = (t5 >>> 11 | t6 << 5) & 8065; this.r[8] = (t6 >>> 8 | t7 << 8) & 8191; this.r[9] = t7 >>> 5 & 127; for (let i2 = 0; i2 < 8; i2++) this.pad[i2] = u8to16(key, 16 + 2 * i2); } process(data, offset, isLast = false) { const hibit = isLast ? 0 : 1 << 11; const { h, r } = this; const r0 = r[0]; const r1 = r[1]; const r2 = r[2]; const r3 = r[3]; const r4 = r[4]; const r5 = r[5]; const r6 = r[6]; const r7 = r[7]; const r8 = r[8]; const r9 = r[9]; const t0 = u8to16(data, offset + 0); const t1 = u8to16(data, offset + 2); const t2 = u8to16(data, offset + 4); const t3 = u8to16(data, offset + 6); const t4 = u8to16(data, offset + 8); const t5 = u8to16(data, offset + 10); const t6 = u8to16(data, offset + 12); const t7 = u8to16(data, offset + 14); let h0 = h[0] + (t0 & 8191); let h1 = h[1] + ((t0 >>> 13 | t1 << 3) & 8191); let h2 = h[2] + ((t1 >>> 10 | t2 << 6) & 8191); let h3 = h[3] + ((t2 >>> 7 | t3 << 9) & 8191); let h4 = h[4] + ((t3 >>> 4 | t4 << 12) & 8191); let h5 = h[5] + (t4 >>> 1 & 8191); let h6 = h[6] + ((t4 >>> 14 | t5 << 2) & 8191); let h7 = h[7] + ((t5 >>> 11 | t6 << 5) & 8191); let h8 = h[8] + ((t6 >>> 8 | t7 << 8) & 8191); let h9 = h[9] + (t7 >>> 5 | hibit); let c = 0; let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6); c = d0 >>> 13; d0 &= 8191; d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1); c += d0 >>> 13; d0 &= 8191; let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7); c = d1 >>> 13; d1 &= 8191; d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2); c += d1 >>> 13; d1 &= 8191; let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8); c = d2 >>> 13; d2 &= 8191; d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3); c += d2 >>> 13; d2 &= 8191; let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9); c = d3 >>> 13; d3 &= 8191; d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4); c += d3 >>> 13; d3 &= 8191; let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0; c = d4 >>> 13; d4 &= 8191; d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5); c += d4 >>> 13; d4 &= 8191; let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1; c = d5 >>> 13; d5 &= 8191; d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6); c += d5 >>> 13; d5 &= 8191; let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2; c = d6 >>> 13; d6 &= 8191; d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7); c += d6 >>> 13; d6 &= 8191; let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3; c = d7 >>> 13; d7 &= 8191; d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8); c += d7 >>> 13; d7 &= 8191; let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4; c = d8 >>> 13; d8 &= 8191; d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9); c += d8 >>> 13; d8 &= 8191; let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5; c = d9 >>> 13; d9 &= 8191; d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0; c += d9 >>> 13; d9 &= 8191; c = (c << 2) + c | 0; c = c + d0 | 0; d0 = c & 8191; c = c >>> 13; d1 += c; h[0] = d0; h[1] = d1; h[2] = d2; h[3] = d3; h[4] = d4; h[5] = d5; h[6] = d6; h[7] = d7; h[8] = d8; h[9] = d9; } finalize() { const { h, pad: pad2 } = this; const g = new Uint16Array(10); let c = h[1] >>> 13; h[1] &= 8191; for (let i2 = 2; i2 < 10; i2++) { h[i2] += c; c = h[i2] >>> 13; h[i2] &= 8191; } h[0] += c * 5; c = h[0] >>> 13; h[0] &= 8191; h[1] += c; c = h[1] >>> 13; h[1] &= 8191; h[2] += c; g[0] = h[0] + 5; c = g[0] >>> 13; g[0] &= 8191; for (let i2 = 1; i2 < 10; i2++) { g[i2] = h[i2] + c; c = g[i2] >>> 13; g[i2] &= 8191; } g[9] -= 1 << 13; let mask = (c ^ 1) - 1; for (let i2 = 0; i2 < 10; i2++) g[i2] &= mask; mask = ~mask; for (let i2 = 0; i2 < 10; i2++) h[i2] = h[i2] & mask | g[i2]; h[0] = (h[0] | h[1] << 13) & 65535; h[1] = (h[1] >>> 3 | h[2] << 10) & 65535; h[2] = (h[2] >>> 6 | h[3] << 7) & 65535; h[3] = (h[3] >>> 9 | h[4] << 4) & 65535; h[4] = (h[4] >>> 12 | h[5] << 1 | h[6] << 14) & 65535; h[5] = (h[6] >>> 2 | h[7] << 11) & 65535; h[6] = (h[7] >>> 5 | h[8] << 8) & 65535; h[7] = (h[8] >>> 8 | h[9] << 5) & 65535; let f = h[0] + pad2[0]; h[0] = f & 65535; for (let i2 = 1; i2 < 8; i2++) { f = (h[i2] + pad2[i2] | 0) + (f >>> 16) | 0; h[i2] = f & 65535; } clean2(g); } update(data) { aexists2(this); abytes3(data); data = copyBytes2(data); const { buffer, blockLen } = this; const len = data.length; for (let pos = 0; pos < len; ) { const take = Math.min(blockLen - this.pos, len - pos); if (take === blockLen) { for (; blockLen <= len - pos; pos += blockLen) this.process(data, pos); continue; } buffer.set(data.subarray(pos, pos + take), this.pos); this.pos += take; pos += take; if (this.pos === blockLen) { this.process(buffer, 0, false); this.pos = 0; } } return this; } destroy() { clean2(this.h, this.r, this.buffer, this.pad); } digestInto(out) { aexists2(this); aoutput2(out, this); this.finished = true; const { buffer, h } = this; let { pos } = this; if (pos) { buffer[pos++] = 1; for (; pos < 16; pos++) buffer[pos] = 0; this.process(buffer, 0, true); } this.finalize(); let opos = 0; for (let i2 = 0; i2 < 8; i2++) { out[opos++] = h[i2] >>> 0; out[opos++] = h[i2] >>> 8; } return out; } digest() { const { buffer, outputLen } = this; this.digestInto(buffer); const res = buffer.slice(0, outputLen); this.destroy(); return res; } }; function wrapConstructorWithKey(hashCons) { const hashC = (msg, key) => hashCons(key).update(msg).digest(); const tmp = hashCons(new Uint8Array(32)); hashC.outputLen = tmp.outputLen; hashC.blockLen = tmp.blockLen; hashC.create = (key) => hashCons(key); return hashC; } var poly1305 = /* @__PURE__ */ (() => wrapConstructorWithKey((key) => new Poly1305(key)))(); // node_modules/@noble/ciphers/chacha.js function chachaCore(s, k, n, out, cnt, rounds = 20) { let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; for (let r = 0; r < rounds; r += 2) { x00 = x00 + x04 | 0; x12 = rotl(x12 ^ x00, 16); x08 = x08 + x12 | 0; x04 = rotl(x04 ^ x08, 12); x00 = x00 + x04 | 0; x12 = rotl(x12 ^ x00, 8); x08 = x08 + x12 | 0; x04 = rotl(x04 ^ x08, 7); x01 = x01 + x05 | 0; x13 = rotl(x13 ^ x01, 16); x09 = x09 + x13 | 0; x05 = rotl(x05 ^ x09, 12); x01 = x01 + x05 | 0; x13 = rotl(x13 ^ x01, 8); x09 = x09 + x13 | 0; x05 = rotl(x05 ^ x09, 7); x02 = x02 + x06 | 0; x14 = rotl(x14 ^ x02, 16); x10 = x10 + x14 | 0; x06 = rotl(x06 ^ x10, 12); x02 = x02 + x06 | 0; x14 = rotl(x14 ^ x02, 8); x10 = x10 + x14 | 0; x06 = rotl(x06 ^ x10, 7); x03 = x03 + x07 | 0; x15 = rotl(x15 ^ x03, 16); x11 = x11 + x15 | 0; x07 = rotl(x07 ^ x11, 12); x03 = x03 + x07 | 0; x15 = rotl(x15 ^ x03, 8); x11 = x11 + x15 | 0; x07 = rotl(x07 ^ x11, 7); x00 = x00 + x05 | 0; x15 = rotl(x15 ^ x00, 16); x10 = x10 + x15 | 0; x05 = rotl(x05 ^ x10, 12); x00 = x00 + x05 | 0; x15 = rotl(x15 ^ x00, 8); x10 = x10 + x15 | 0; x05 = rotl(x05 ^ x10, 7); x01 = x01 + x06 | 0; x12 = rotl(x12 ^ x01, 16); x11 = x11 + x12 | 0; x06 = rotl(x06 ^ x11, 12); x01 = x01 + x06 | 0; x12 = rotl(x12 ^ x01, 8); x11 = x11 + x12 | 0; x06 = rotl(x06 ^ x11, 7); x02 = x02 + x07 | 0; x13 = rotl(x13 ^ x02, 16); x08 = x08 + x13 | 0; x07 = rotl(x07 ^ x08, 12); x02 = x02 + x07 | 0; x13 = rotl(x13 ^ x02, 8); x08 = x08 + x13 | 0; x07 = rotl(x07 ^ x08, 7); x03 = x03 + x04 | 0; x14 = rotl(x14 ^ x03, 16); x09 = x09 + x14 | 0; x04 = rotl(x04 ^ x09, 12); x03 = x03 + x04 | 0; x14 = rotl(x14 ^ x03, 8); x09 = x09 + x14 | 0; x04 = rotl(x04 ^ x09, 7); } let oi = 0; out[oi++] = y00 + x00 | 0; out[oi++] = y01 + x01 | 0; out[oi++] = y02 + x02 | 0; out[oi++] = y03 + x03 | 0; out[oi++] = y04 + x04 | 0; out[oi++] = y05 + x05 | 0; out[oi++] = y06 + x06 | 0; out[oi++] = y07 + x07 | 0; out[oi++] = y08 + x08 | 0; out[oi++] = y09 + x09 | 0; out[oi++] = y10 + x10 | 0; out[oi++] = y11 + x11 | 0; out[oi++] = y12 + x12 | 0; out[oi++] = y13 + x13 | 0; out[oi++] = y14 + x14 | 0; out[oi++] = y15 + x15 | 0; } function hchacha(s, k, i2, out) { let x00 = s[0], x01 = s[1], x02 = s[2], x03 = s[3], x04 = k[0], x05 = k[1], x06 = k[2], x07 = k[3], x08 = k[4], x09 = k[5], x10 = k[6], x11 = k[7], x12 = i2[0], x13 = i2[1], x14 = i2[2], x15 = i2[3]; for (let r = 0; r < 20; r += 2) { x00 = x00 + x04 | 0; x12 = rotl(x12 ^ x00, 16); x08 = x08 + x12 | 0; x04 = rotl(x04 ^ x08, 12); x00 = x00 + x04 | 0; x12 = rotl(x12 ^ x00, 8); x08 = x08 + x12 | 0; x04 = rotl(x04 ^ x08, 7); x01 = x01 + x05 | 0; x13 = rotl(x13 ^ x01, 16); x09 = x09 + x13 | 0; x05 = rotl(x05 ^ x09, 12); x01 = x01 + x05 | 0; x13 = rotl(x13 ^ x01, 8); x09 = x09 + x13 | 0; x05 = rotl(x05 ^ x09, 7); x02 = x02 + x06 | 0; x14 = rotl(x14 ^ x02, 16); x10 = x10 + x14 | 0; x06 = rotl(x06 ^ x10, 12); x02 = x02 + x06 | 0; x14 = rotl(x14 ^ x02, 8); x10 = x10 + x14 | 0; x06 = rotl(x06 ^ x10, 7); x03 = x03 + x07 | 0; x15 = rotl(x15 ^ x03, 16); x11 = x11 + x15 | 0; x07 = rotl(x07 ^ x11, 12); x03 = x03 + x07 | 0; x15 = rotl(x15 ^ x03, 8); x11 = x11 + x15 | 0; x07 = rotl(x07 ^ x11, 7); x00 = x00 + x05 | 0; x15 = rotl(x15 ^ x00, 16); x10 = x10 + x15 | 0; x05 = rotl(x05 ^ x10, 12); x00 = x00 + x05 | 0; x15 = rotl(x15 ^ x00, 8); x10 = x10 + x15 | 0; x05 = rotl(x05 ^ x10, 7); x01 = x01 + x06 | 0; x12 = rotl(x12 ^ x01, 16); x11 = x11 + x12 | 0; x06 = rotl(x06 ^ x11, 12); x01 = x01 + x06 | 0; x12 = rotl(x12 ^ x01, 8); x11 = x11 + x12 | 0; x06 = rotl(x06 ^ x11, 7); x02 = x02 + x07 | 0; x13 = rotl(x13 ^ x02, 16); x08 = x08 + x13 | 0; x07 = rotl(x07 ^ x08, 12); x02 = x02 + x07 | 0; x13 = rotl(x13 ^ x02, 8); x08 = x08 + x13 | 0; x07 = rotl(x07 ^ x08, 7); x03 = x03 + x04 | 0; x14 = rotl(x14 ^ x03, 16); x09 = x09 + x14 | 0; x04 = rotl(x04 ^ x09, 12); x03 = x03 + x04 | 0; x14 = rotl(x14 ^ x03, 8); x09 = x09 + x14 | 0; x04 = rotl(x04 ^ x09, 7); } let oi = 0; out[oi++] = x00; out[oi++] = x01; out[oi++] = x02; out[oi++] = x03; out[oi++] = x12; out[oi++] = x13; out[oi++] = x14; out[oi++] = x15; } var chacha20 = /* @__PURE__ */ createCipher(chachaCore, { counterRight: false, counterLength: 4, allowShortKeys: false }); var xchacha20 = /* @__PURE__ */ createCipher(chachaCore, { counterRight: false, counterLength: 8, extendNonceFn: hchacha, allowShortKeys: false }); var ZEROS16 = /* @__PURE__ */ new Uint8Array(16); var updatePadded = (h, msg) => { h.update(msg); const leftover = msg.length % 16; if (leftover) h.update(ZEROS16.subarray(leftover)); }; var ZEROS32 = /* @__PURE__ */ new Uint8Array(32); function computeTag(fn, key, nonce, ciphertext, AAD) { if (AAD !== void 0) abytes3(AAD, void 0, "AAD"); const authKey = fn(key, nonce, ZEROS32); const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true); const h = poly1305.create(authKey); if (AAD) updatePadded(h, AAD); updatePadded(h, ciphertext); h.update(lengths); const res = h.digest(); clean2(authKey, lengths); return res; } var _poly1305_aead = (xorStream) => (key, nonce, AAD) => { const tagLength = 16; return { encrypt(plaintext, output) { const plength = plaintext.length; output = getOutput(plength + tagLength, output, false); output.set(plaintext); const oPlain = output.subarray(0, -tagLength); xorStream(key, nonce, oPlain, oPlain, 1); const tag = computeTag(xorStream, key, nonce, oPlain, AAD); output.set(tag, plength); clean2(tag); return output; }, decrypt(ciphertext, output) { output = getOutput(ciphertext.length - tagLength, output, false); const data = ciphertext.subarray(0, -tagLength); const passedTag = ciphertext.subarray(-tagLength); const tag = computeTag(xorStream, key, nonce, data, AAD); if (!equalBytes(passedTag, tag)) throw new Error("invalid tag"); output.set(ciphertext.subarray(0, -tagLength)); xorStream(key, nonce, output, output, 1); clean2(tag); return output; } }; }; var chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20)); var xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20)); // node_modules/@noble/hashes/hkdf.js function extract(hash, ikm, salt) { ahash(hash); if (salt === void 0) salt = new Uint8Array(hash.outputLen); return hmac(hash, salt, ikm); } var HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0); var EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of(); function expand(hash, prk, info, length = 32) { ahash(hash); anumber(length, "length"); const olen = hash.outputLen; if (length > 255 * olen) throw new Error("Length must be <= 255*HashLen"); const blocks = Math.ceil(length / olen); if (info === void 0) info = EMPTY_BUFFER; else abytes(info, void 0, "info"); const okm = new Uint8Array(blocks * olen); const HMAC = hmac.create(hash, prk); const HMACTmp = HMAC._cloneInto(); const T = new Uint8Array(HMAC.outputLen); for (let counter = 0; counter < blocks; counter++) { HKDF_COUNTER[0] = counter + 1; HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T).update(info).update(HKDF_COUNTER).digestInto(T); okm.set(T, olen * counter); HMAC._cloneInto(HMACTmp); } HMAC.destroy(); HMACTmp.destroy(); clean(T, HKDF_COUNTER); return okm.slice(0, length); } // nip44.ts var minPlaintextSize = 1; var maxPlaintextSize = 65535; function getConversationKey(privkeyA, pubkeyB) { const sharedX = secp256k1.getSharedSecret(privkeyA, hexToBytes("02" + pubkeyB)).subarray(1, 33); return extract(sha256, sharedX, utf8Encoder.encode("nip44-v2")); } function getMessageKeys(conversationKey, nonce) { const keys = expand(sha256, conversationKey, nonce, 76); return { chacha_key: keys.subarray(0, 32), chacha_nonce: keys.subarray(32, 44), hmac_key: keys.subarray(44, 76) }; } function calcPaddedLen(len) { if (!Number.isSafeInteger(len) || len < 1) throw new Error("expected positive integer"); if (len <= 32) return 32; const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1; const chunk = nextPower <= 256 ? 32 : nextPower / 8; return chunk * (Math.floor((len - 1) / chunk) + 1); } function writeU16BE(num2) { if (!Number.isSafeInteger(num2) || num2 < minPlaintextSize || num2 > maxPlaintextSize) throw new Error("invalid plaintext size: must be between 1 and 65535 bytes"); const arr = new Uint8Array(2); new DataView(arr.buffer).setUint16(0, num2, false); return arr; } function pad(plaintext) { const unpadded = utf8Encoder.encode(plaintext); const unpaddedLen = unpadded.length; const prefix = writeU16BE(unpaddedLen); const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen); return concatBytes(prefix, unpadded, suffix); } function unpad(padded) { const unpaddedLen = new DataView(padded.buffer).getUint16(0); const unpadded = padded.subarray(2, 2 + unpaddedLen); if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + calcPaddedLen(unpaddedLen)) throw new Error("invalid padding"); return utf8Decoder.decode(unpadded); } function hmacAad(key, message, aad) { if (aad.length !== 32) throw new Error("AAD associated data must be 32 bytes"); const combined = concatBytes(aad, message); return hmac(sha256, key, combined); } function decodePayload(payload) { if (typeof payload !== "string") throw new Error("payload must be a valid string"); const plen = payload.length; if (plen < 132 || plen > 87472) throw new Error("invalid payload length: " + plen); if (payload[0] === "#") throw new Error("unknown encryption version"); let data; try { data = base64.decode(payload); } catch (error) { throw new Error("invalid base64: " + error.message); } const dlen = data.length; if (dlen < 99 || dlen > 65603) throw new Error("invalid data length: " + dlen); const vers = data[0]; if (vers !== 2) throw new Error("unknown encryption version " + vers); return { nonce: data.subarray(1, 33), ciphertext: data.subarray(33, -32), mac: data.subarray(-32) }; } function encrypt3(plaintext, conversationKey, nonce = randomBytes(32)) { const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce); const padded = pad(plaintext); const ciphertext = chacha20(chacha_key, chacha_nonce, padded); const mac = hmacAad(hmac_key, ciphertext, nonce); return base64.encode(concatBytes(new Uint8Array([2]), nonce, ciphertext, mac)); } function decrypt3(payload, conversationKey) { const { nonce, ciphertext, mac } = decodePayload(payload); const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce); const calculatedMac = hmacAad(hmac_key, ciphertext, nonce); if (!equalBytes(calculatedMac, mac)) throw new Error("invalid MAC"); const padded = chacha20(chacha_key, chacha_nonce, ciphertext); return unpad(padded); } var v2 = { utils: { getConversationKey, calcPaddedLen }, encrypt: encrypt3, decrypt: decrypt3 }; // nip59.ts var TWO_DAYS = 2 * 24 * 60 * 60; var now = () => Math.round(Date.now() / 1e3); var randomNow = () => Math.round(now() - Math.random() * TWO_DAYS); var nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey); var nip44Encrypt = (data, privateKey, publicKey) => encrypt3(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey)); var nip44Decrypt = (data, privateKey) => JSON.parse(decrypt3(data.content, nip44ConversationKey(privateKey, data.pubkey))); function createRumor(event, privateKey) { const rumor = { created_at: now(), content: "", tags: [], ...event, pubkey: getPublicKey(privateKey) }; rumor.id = getEventHash(rumor); return rumor; } function createSeal(rumor, privateKey, recipientPublicKey) { return finalizeEvent( { kind: Seal, content: nip44Encrypt(rumor, privateKey, recipientPublicKey), created_at: randomNow(), tags: [] }, privateKey ); } function createWrap(seal, recipientPublicKey) { const randomKey = generateSecretKey(); return finalizeEvent( { kind: GiftWrap, content: nip44Encrypt(seal, randomKey, recipientPublicKey), created_at: randomNow(), tags: [["p", recipientPublicKey]] }, randomKey ); } function wrapEvent(event, senderPrivateKey, recipientPublicKey) { const rumor = createRumor(event, senderPrivateKey); const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey); return createWrap(seal, recipientPublicKey); } function wrapManyEvents(event, senderPrivateKey, recipientsPublicKeys) { if (!recipientsPublicKeys || recipientsPublicKeys.length === 0) { throw new Error("At least one recipient is required."); } const senderPublicKey = getPublicKey(senderPrivateKey); const wrappeds = [wrapEvent(event, senderPrivateKey, senderPublicKey)]; recipientsPublicKeys.forEach((recipientPublicKey) => { wrappeds.push(wrapEvent(event, senderPrivateKey, recipientPublicKey)); }); return wrappeds; } function unwrapEvent(wrap, recipientPrivateKey) { const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey); return nip44Decrypt(unwrappedSeal, recipientPrivateKey); } function unwrapManyEvents(wrappedEvents, recipientPrivateKey) { let unwrappedEvents = []; wrappedEvents.forEach((e) => { unwrappedEvents.push(unwrapEvent(e, recipientPrivateKey)); }); unwrappedEvents.sort((a, b) => a.created_at - b.created_at); return unwrappedEvents; } // nip17.ts function createEvent(recipients, message, conversationTitle, replyTo) { const baseEvent = { created_at: Math.ceil(Date.now() / 1e3), kind: PrivateDirectMessage, tags: [], content: message }; const recipientsArray = Array.isArray(recipients) ? recipients : [recipients]; recipientsArray.forEach(({ publicKey, relayUrl }) => { baseEvent.tags.push(relayUrl ? ["p", publicKey, relayUrl] : ["p", publicKey]); }); if (replyTo) { baseEvent.tags.push(["e", replyTo.eventId, replyTo.relayUrl || "", "reply"]); } if (conversationTitle) { baseEvent.tags.push(["subject", conversationTitle]); } return baseEvent; } function wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo) { const event = createEvent(recipient, message, conversationTitle, replyTo); return wrapEvent(event, senderPrivateKey, recipient.publicKey); } function wrapManyEvents2(senderPrivateKey, recipients, message, conversationTitle, replyTo) { if (!recipients || recipients.length === 0) { throw new Error("At least one recipient is required."); } const senderPublicKey = getPublicKey(senderPrivateKey); return [{ publicKey: senderPublicKey }, ...recipients].map( (recipient) => wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo) ); } var unwrapEvent2 = unwrapEvent; var unwrapManyEvents2 = unwrapManyEvents; // nip18.ts var nip18_exports = {}; __export(nip18_exports, { finishRepostEvent: () => finishRepostEvent, getRepostedEvent: () => getRepostedEvent, getRepostedEventPointer: () => getRepostedEventPointer }); function finishRepostEvent(t, reposted, relayUrl, privateKey) { let kind; const tags = [...t.tags ?? [], ["e", reposted.id, relayUrl], ["p", reposted.pubkey]]; if (reposted.kind === ShortTextNote) { kind = Repost; } else { kind = GenericRepost; tags.push(["k", String(reposted.kind)]); } return finalizeEvent( { kind, tags, content: t.content === "" || reposted.tags?.find((tag) => tag[0] === "-") ? "" : JSON.stringify(reposted), created_at: t.created_at }, privateKey ); } function getRepostedEventPointer(event) { if (![Repost, GenericRepost].includes(event.kind)) { return void 0; } let lastETag; let lastPTag; for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) { const tag = event.tags[i2]; if (tag.length >= 2) { if (tag[0] === "e" && lastETag === void 0) { lastETag = tag; } else if (tag[0] === "p" && lastPTag === void 0) { lastPTag = tag; } } } if (lastETag === void 0) { return void 0; } return { id: lastETag[1], relays: [lastETag[2], lastPTag?.[2]].filter((x) => typeof x === "string"), author: lastPTag?.[1] }; } function getRepostedEvent(event, { skipVerification } = {}) { const pointer = getRepostedEventPointer(event); if (pointer === void 0 || event.content === "") { return void 0; } let repostedEvent; try { repostedEvent = JSON.parse(event.content); } catch (error) { return void 0; } if (repostedEvent.id !== pointer.id) { return void 0; } if (!skipVerification && !verifyEvent(repostedEvent)) { return void 0; } return repostedEvent; } // nip21.ts var nip21_exports = {}; __export(nip21_exports, { NOSTR_URI_REGEX: () => NOSTR_URI_REGEX, parse: () => parse2, test: () => test }); var NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`); function test(value) { return typeof value === "string" && new RegExp(`^${NOSTR_URI_REGEX.source}$`).test(value); } function parse2(uri) { const match = uri.match(new RegExp(`^${NOSTR_URI_REGEX.source}$`)); if (!match) throw new Error(`Invalid Nostr URI: ${uri}`); return { uri: match[0], value: match[1], decoded: decode(match[1]) }; } // nip25.ts var nip25_exports = {}; __export(nip25_exports, { finishReactionEvent: () => finishReactionEvent, getReactedEventPointer: () => getReactedEventPointer }); function finishReactionEvent(t, reacted, privateKey) { const inheritedTags = reacted.tags.filter((tag) => tag.length >= 2 && (tag[0] === "e" || tag[0] === "p")); return finalizeEvent( { ...t, kind: Reaction, tags: [...t.tags ?? [], ...inheritedTags, ["e", reacted.id], ["p", reacted.pubkey]], content: t.content ?? "+" }, privateKey ); } function getReactedEventPointer(event) { if (event.kind !== Reaction) { return void 0; } let lastETag; let lastPTag; for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) { const tag = event.tags[i2]; if (tag.length >= 2) { if (tag[0] === "e" && lastETag === void 0) { lastETag = tag; } else if (tag[0] === "p" && lastPTag === void 0) { lastPTag = tag; } } } if (lastETag === void 0 || lastPTag === void 0) { return void 0; } return { id: lastETag[1], relays: [lastETag[2], lastPTag[2]].filter((x) => x !== void 0), author: lastPTag[1] }; } // nip27.ts var nip27_exports = {}; __export(nip27_exports, { parse: () => parse3 }); var noCharacter = /\W/m; var noURLCharacter = /[^\w\/] |[^\w\/]$|$|,| /m; var MAX_HASHTAG_LENGTH = 42; function* parse3(content) { let emojis = []; if (typeof content !== "string") { for (let i2 = 0; i2 < content.tags.length; i2++) { const tag = content.tags[i2]; if (tag[0] === "emoji" && tag.length >= 3) { emojis.push({ type: "emoji", shortcode: tag[1], url: tag[2] }); } } content = content.content; } const max = content.length; let prevIndex = 0; let index = 0; mainloop: while (index < max) { const u = content.indexOf(":", index); const h = content.indexOf("#", index); if (u === -1 && h === -1) { break mainloop; } if (u === -1 || h >= 0 && h < u) { if (h === 0 || content[h - 1].match(noCharacter)) { const m = content.slice(h + 1, h + MAX_HASHTAG_LENGTH).match(noCharacter); const end = m ? h + 1 + m.index : max; yield { type: "text", text: content.slice(prevIndex, h) }; yield { type: "hashtag", value: content.slice(h + 1, end) }; index = end; prevIndex = index; continue mainloop; } index = h + 1; continue mainloop; } if (content.slice(u - 5, u) === "nostr") { const m = content.slice(u + 60).match(noCharacter); const end = m ? u + 60 + m.index : max; try { let pointer; let { data, type } = decode(content.slice(u + 1, end)); switch (type) { case "npub": pointer = { pubkey: data }; break; case "note": pointer = { id: data }; break; case "nsec": index = end + 1; continue; default: pointer = data; } if (prevIndex !== u - 5) { yield { type: "text", text: content.slice(prevIndex, u - 5) }; } yield { type: "reference", pointer }; index = end; prevIndex = index; continue mainloop; } catch (_err) { index = u + 1; continue mainloop; } } else if (content.slice(u - 5, u) === "https" || content.slice(u - 4, u) === "http") { const m = content.slice(u + 4).match(noURLCharacter); const end = m ? u + 4 + m.index : max; const prefixLen = content[u - 1] === "s" ? 5 : 4; try { let url = new URL(content.slice(u - prefixLen, end)); if (url.hostname.indexOf(".") === -1) { throw new Error("invalid url"); } if (prevIndex !== u - prefixLen) { yield { type: "text", text: content.slice(prevIndex, u - prefixLen) }; } if (/\.(png|jpe?g|gif|webp|heic|svg)$/i.test(url.pathname)) { yield { type: "image", url: url.toString() }; index = end; prevIndex = index; continue mainloop; } if (/\.(mp4|avi|webm|mkv|mov)$/i.test(url.pathname)) { yield { type: "video", url: url.toString() }; index = end; prevIndex = index; continue mainloop; } if (/\.(mp3|aac|ogg|opus|wav|flac)$/i.test(url.pathname)) { yield { type: "audio", url: url.toString() }; index = end; prevIndex = index; continue mainloop; } yield { type: "url", url: url.toString() }; index = end; prevIndex = index; continue mainloop; } catch (_err) { index = end + 1; continue mainloop; } } else if (content.slice(u - 3, u) === "wss" || content.slice(u - 2, u) === "ws") { const m = content.slice(u + 4).match(noURLCharacter); const end = m ? u + 4 + m.index : max; const prefixLen = content[u - 1] === "s" ? 3 : 2; try { let url = new URL(content.slice(u - prefixLen, end)); if (url.hostname.indexOf(".") === -1) { throw new Error("invalid ws url"); } if (prevIndex !== u - prefixLen) { yield { type: "text", text: content.slice(prevIndex, u - prefixLen) }; } yield { type: "relay", url: url.toString() }; index = end; prevIndex = index; continue mainloop; } catch (_err) { index = end + 1; continue mainloop; } } else { for (let e = 0; e < emojis.length; e++) { const emoji = emojis[e]; if (content[u + emoji.shortcode.length + 1] === ":" && content.slice(u + 1, u + emoji.shortcode.length + 1) === emoji.shortcode) { if (prevIndex !== u) { yield { type: "text", text: content.slice(prevIndex, u) }; } yield emoji; index = u + emoji.shortcode.length + 2; prevIndex = index; continue mainloop; } } index = u + 1; continue mainloop; } } if (prevIndex !== max) { yield { type: "text", text: content.slice(prevIndex) }; } } // nip28.ts var nip28_exports = {}; __export(nip28_exports, { channelCreateEvent: () => channelCreateEvent, channelHideMessageEvent: () => channelHideMessageEvent, channelMessageEvent: () => channelMessageEvent, channelMetadataEvent: () => channelMetadataEvent, channelMuteUserEvent: () => channelMuteUserEvent }); var channelCreateEvent = (t, privateKey) => { let content; if (typeof t.content === "object") { content = JSON.stringify(t.content); } else if (typeof t.content === "string") { content = t.content; } else { return void 0; } return finalizeEvent( { kind: ChannelCreation, tags: [...t.tags ?? []], content, created_at: t.created_at }, privateKey ); }; var channelMetadataEvent = (t, privateKey) => { let content; if (typeof t.content === "object") { content = JSON.stringify(t.content); } else if (typeof t.content === "string") { content = t.content; } else { return void 0; } return finalizeEvent( { kind: ChannelMetadata, tags: [["e", t.channel_create_event_id], ...t.tags ?? []], content, created_at: t.created_at }, privateKey ); }; var channelMessageEvent = (t, privateKey) => { const tags = [["e", t.channel_create_event_id, t.relay_url, "root"]]; if (t.reply_to_channel_message_event_id) { tags.push(["e", t.reply_to_channel_message_event_id, t.relay_url, "reply"]); } return finalizeEvent( { kind: ChannelMessage, tags: [...tags, ...t.tags ?? []], content: t.content, created_at: t.created_at }, privateKey ); }; var channelHideMessageEvent = (t, privateKey) => { let content; if (typeof t.content === "object") { content = JSON.stringify(t.content); } else if (typeof t.content === "string") { content = t.content; } else { return void 0; } return finalizeEvent( { kind: ChannelHideMessage, tags: [["e", t.channel_message_event_id], ...t.tags ?? []], content, created_at: t.created_at }, privateKey ); }; var channelMuteUserEvent = (t, privateKey) => { let content; if (typeof t.content === "object") { content = JSON.stringify(t.content); } else if (typeof t.content === "string") { content = t.content; } else { return void 0; } return finalizeEvent( { kind: ChannelMuteUser, tags: [["p", t.pubkey_to_mute], ...t.tags ?? []], content, created_at: t.created_at }, privateKey ); }; // nip30.ts var nip30_exports = {}; __export(nip30_exports, { EMOJI_SHORTCODE_REGEX: () => EMOJI_SHORTCODE_REGEX, matchAll: () => matchAll, regex: () => regex, replaceAll: () => replaceAll }); var EMOJI_SHORTCODE_REGEX = /:(\w+):/; var regex = () => new RegExp(`\\B${EMOJI_SHORTCODE_REGEX.source}\\B`, "g"); function* matchAll(content) { const matches = content.matchAll(regex()); for (const match of matches) { try { const [shortcode, name] = match; yield { shortcode, name, start: match.index, end: match.index + shortcode.length }; } catch (_e) { } } } function replaceAll(content, replacer) { return content.replaceAll(regex(), (shortcode, name) => { return replacer({ shortcode, name }); }); } // nip39.ts var nip39_exports = {}; __export(nip39_exports, { useFetchImplementation: () => useFetchImplementation3, validateGithub: () => validateGithub }); var _fetch3; try { _fetch3 = fetch; } catch { } function useFetchImplementation3(fetchImplementation) { _fetch3 = fetchImplementation; } async function validateGithub(pubkey, username, proof) { try { let res = await (await _fetch3(`https://gist.github.com/${username}/${proof}/raw`)).text(); return res === `Verifying that I control the following Nostr public key: ${pubkey}`; } catch (_) { return false; } } // nip47.ts var nip47_exports = {}; __export(nip47_exports, { makeNwcRequestEvent: () => makeNwcRequestEvent, parseConnectionString: () => parseConnectionString }); function parseConnectionString(connectionString) { const { host, pathname, searchParams } = new URL(connectionString); const pubkey = pathname || host; const relay = searchParams.get("relay"); const secret = searchParams.get("secret"); if (!pubkey || !relay || !secret) { throw new Error("invalid connection string"); } return { pubkey, relay, secret }; } async function makeNwcRequestEvent(pubkey, secretKey, invoice) { const content = { method: "pay_invoice", params: { invoice } }; const encryptedContent = encrypt2(secretKey, pubkey, JSON.stringify(content)); const eventTemplate = { kind: NWCWalletRequest, created_at: Math.round(Date.now() / 1e3), content: encryptedContent, tags: [["p", pubkey]] }; return finalizeEvent(eventTemplate, secretKey); } // nip54.ts var nip54_exports = {}; __export(nip54_exports, { normalizeIdentifier: () => normalizeIdentifier }); function normalizeIdentifier(name) { name = name.trim().toLowerCase(); name = name.normalize("NFKC"); return Array.from(name).map((char) => { if (/\p{Letter}/u.test(char) || /\p{Number}/u.test(char)) { return char; } return "-"; }).join(""); } // nip57.ts var nip57_exports = {}; __export(nip57_exports, { getSatoshisAmountFromBolt11: () => getSatoshisAmountFromBolt11, getZapEndpoint: () => getZapEndpoint, makeZapReceipt: () => makeZapReceipt, makeZapRequest: () => makeZapRequest, useFetchImplementation: () => useFetchImplementation4, validateZapRequest: () => validateZapRequest }); var _fetch4; try { _fetch4 = fetch; } catch { } function useFetchImplementation4(fetchImplementation) { _fetch4 = fetchImplementation; } async function getZapEndpoint(metadata) { try { let lnurl = ""; let { lud06, lud16 } = JSON.parse(metadata.content); if (lud16) { let [name, domain] = lud16.split("@"); lnurl = new URL(`/.well-known/lnurlp/${name}`, `https://${domain}`).toString(); } else if (lud06) { let { words } = bech32.decode(lud06, 1e3); let data = bech32.fromWords(words); lnurl = utf8Decoder.decode(data); } else { return null; } let res = await _fetch4(lnurl); let body = await res.json(); if (body.allowsNostr && body.nostrPubkey) { return body.callback; } } catch (err) { } return null; } function makeZapRequest(params) { let zr = { kind: 9734, created_at: Math.round(Date.now() / 1e3), content: params.comment || "", tags: [ ["p", "pubkey" in params ? params.pubkey : params.event.pubkey], ["amount", params.amount.toString()], ["relays", ...params.relays] ] }; if ("event" in params) { zr.tags.push(["e", params.event.id]); if (isReplaceableKind(params.event.kind)) { const a = ["a", `${params.event.kind}:${params.event.pubkey}:`]; zr.tags.push(a); } else if (isAddressableKind(params.event.kind)) { let d = params.event.tags.find(([t, v]) => t === "d" && v); if (!d) throw new Error("d tag not found or is empty"); const a = ["a", `${params.event.kind}:${params.event.pubkey}:${d[1]}`]; zr.tags.push(a); } zr.tags.push(["k", params.event.kind.toString()]); } return zr; } function validateZapRequest(zapRequestString) { let zapRequest; try { zapRequest = JSON.parse(zapRequestString); } catch (err) { return "Invalid zap request JSON."; } if (!validateEvent(zapRequest)) return "Zap request is not a valid Nostr event."; if (!verifyEvent(zapRequest)) return "Invalid signature on zap request."; let p = zapRequest.tags.find(([t, v]) => t === "p" && v); if (!p) return "Zap request doesn't have a 'p' tag."; if (!p[1].match(/^[a-f0-9]{64}$/)) return "Zap request 'p' tag is not valid hex."; let e = zapRequest.tags.find(([t, v]) => t === "e" && v); if (e && !e[1].match(/^[a-f0-9]{64}$/)) return "Zap request 'e' tag is not valid hex."; let relays = zapRequest.tags.find(([t, v]) => t === "relays" && v); if (!relays) return "Zap request doesn't have a 'relays' tag."; return null; } function makeZapReceipt({ zapRequest, preimage, bolt11, paidAt }) { let zr = JSON.parse(zapRequest); let tagsFromZapRequest = zr.tags.filter(([t]) => t === "e" || t === "p" || t === "a"); let zap = { kind: 9735, created_at: Math.round(paidAt.getTime() / 1e3), content: "", tags: [...tagsFromZapRequest, ["P", zr.pubkey], ["bolt11", bolt11], ["description", zapRequest]] }; if (preimage) { zap.tags.push(["preimage", preimage]); } return zap; } function getSatoshisAmountFromBolt11(bolt11) { if (bolt11.length < 50) { return 0; } bolt11 = bolt11.substring(0, 50); const idx = bolt11.lastIndexOf("1"); if (idx === -1) { return 0; } const hrp = bolt11.substring(0, idx); if (!hrp.startsWith("lnbc")) { return 0; } const amount = hrp.substring(4); if (amount.length < 1) { return 0; } const char = amount[amount.length - 1]; const digit = char.charCodeAt(0) - "0".charCodeAt(0); const isDigit = digit >= 0 && digit <= 9; let cutPoint = amount.length - 1; if (isDigit) { cutPoint++; } if (cutPoint < 1) { return 0; } const num2 = parseInt(amount.substring(0, cutPoint)); switch (char) { case "m": return num2 * 1e5; case "u": return num2 * 100; case "n": return num2 / 10; case "p": return num2 / 1e4; default: return num2 * 1e8; } } // nip77.ts var nip77_exports = {}; __export(nip77_exports, { Negentropy: () => Negentropy, NegentropyStorageVector: () => NegentropyStorageVector, NegentropySync: () => NegentropySync }); var PROTOCOL_VERSION = 97; var ID_SIZE = 32; var FINGERPRINT_SIZE = 16; var Mode = { Skip: 0, Fingerprint: 1, IdList: 2 }; var WrappedBuffer = class { _raw; length; constructor(buffer) { if (typeof buffer === "number") { this._raw = new Uint8Array(buffer); this.length = 0; } else if (buffer instanceof Uint8Array) { this._raw = new Uint8Array(buffer); this.length = buffer.length; } else { this._raw = new Uint8Array(512); this.length = 0; } } unwrap() { return this._raw.subarray(0, this.length); } get capacity() { return this._raw.byteLength; } extend(buf) { if (buf instanceof WrappedBuffer) buf = buf.unwrap(); if (typeof buf.length !== "number") throw Error("bad length"); const targetSize = buf.length + this.length; if (this.capacity < targetSize) { const oldRaw = this._raw; const newCapacity = Math.max(this.capacity * 2, targetSize); this._raw = new Uint8Array(newCapacity); this._raw.set(oldRaw); } this._raw.set(buf, this.length); this.length += buf.length; } shift() { const first = this._raw[0]; this._raw = this._raw.subarray(1); this.length--; return first; } shiftN(n = 1) { const firstSubarray = this._raw.subarray(0, n); this._raw = this._raw.subarray(n); this.length -= n; return firstSubarray; } }; function decodeVarInt(buf) { let res = 0; while (1) { if (buf.length === 0) throw Error("parse ends prematurely"); let byte = buf.shift(); res = res << 7 | byte & 127; if ((byte & 128) === 0) break; } return res; } function encodeVarInt(n) { if (n === 0) return new WrappedBuffer(new Uint8Array([0])); let o = []; while (n !== 0) { o.push(n & 127); n >>>= 7; } o.reverse(); for (let i2 = 0; i2 < o.length - 1; i2++) o[i2] |= 128; return new WrappedBuffer(new Uint8Array(o)); } function getByte(buf) { return getBytes(buf, 1)[0]; } function getBytes(buf, n) { if (buf.length < n) throw Error("parse ends prematurely"); return buf.shiftN(n); } var Accumulator = class { buf; constructor() { this.setToZero(); } setToZero() { this.buf = new Uint8Array(ID_SIZE); } add(otherBuf) { let currCarry = 0, nextCarry = 0; let p = new DataView(this.buf.buffer); let po = new DataView(otherBuf.buffer); for (let i2 = 0; i2 < 8; i2++) { let offset = i2 * 4; let orig = p.getUint32(offset, true); let otherV = po.getUint32(offset, true); let next = orig; next += currCarry; next += otherV; if (next > 4294967295) nextCarry = 1; p.setUint32(offset, next & 4294967295, true); currCarry = nextCarry; nextCarry = 0; } } negate() { let p = new DataView(this.buf.buffer); for (let i2 = 0; i2 < 8; i2++) { let offset = i2 * 4; p.setUint32(offset, ~p.getUint32(offset, true)); } let one = new Uint8Array(ID_SIZE); one[0] = 1; this.add(one); } getFingerprint(n) { let input = new WrappedBuffer(); input.extend(this.buf); input.extend(encodeVarInt(n)); let hash = sha256(input.unwrap()); return hash.subarray(0, FINGERPRINT_SIZE); } }; var NegentropyStorageVector = class { items; sealed; constructor() { this.items = []; this.sealed = false; } insert(timestamp, id) { if (this.sealed) throw Error("already sealed"); const idb = hexToBytes(id); if (idb.byteLength !== ID_SIZE) throw Error("bad id size for added item"); this.items.push({ timestamp, id: idb }); } seal() { if (this.sealed) throw Error("already sealed"); this.sealed = true; this.items.sort(itemCompare); for (let i2 = 1; i2 < this.items.length; i2++) { if (itemCompare(this.items[i2 - 1], this.items[i2]) === 0) throw Error("duplicate item inserted"); } } unseal() { this.sealed = false; } size() { this._checkSealed(); return this.items.length; } getItem(i2) { this._checkSealed(); if (i2 >= this.items.length) throw Error("out of range"); return this.items[i2]; } iterate(begin, end, cb) { this._checkSealed(); this._checkBounds(begin, end); for (let i2 = begin; i2 < end; ++i2) { if (!cb(this.items[i2], i2)) break; } } findLowerBound(begin, end, bound) { this._checkSealed(); this._checkBounds(begin, end); return this._binarySearch(this.items, begin, end, (a) => itemCompare(a, bound) < 0); } fingerprint(begin, end) { let out = new Accumulator(); out.setToZero(); this.iterate(begin, end, (item) => { out.add(item.id); return true; }); return out.getFingerprint(end - begin); } _checkSealed() { if (!this.sealed) throw Error("not sealed"); } _checkBounds(begin, end) { if (begin > end || end > this.items.length) throw Error("bad range"); } _binarySearch(arr, first, last, cmp) { let count = last - first; while (count > 0) { let it = first; let step = Math.floor(count / 2); it += step; if (cmp(arr[it])) { first = ++it; count -= step + 1; } else { count = step; } } return first; } }; var Negentropy = class { storage; frameSizeLimit; lastTimestampIn; lastTimestampOut; constructor(storage, frameSizeLimit = 6e4) { if (frameSizeLimit < 4096) throw Error("frameSizeLimit too small"); this.storage = storage; this.frameSizeLimit = frameSizeLimit; this.lastTimestampIn = 0; this.lastTimestampOut = 0; } _bound(timestamp, id) { return { timestamp, id: id || new Uint8Array(0) }; } initiate() { let output = new WrappedBuffer(); output.extend(new Uint8Array([PROTOCOL_VERSION])); this.splitRange(0, this.storage.size(), this._bound(Number.MAX_VALUE), output); return bytesToHex(output.unwrap()); } reconcile(queryMsg, onhave, onneed) { const query = new WrappedBuffer(hexToBytes(queryMsg)); this.lastTimestampIn = this.lastTimestampOut = 0; let fullOutput = new WrappedBuffer(); fullOutput.extend(new Uint8Array([PROTOCOL_VERSION])); let protocolVersion = getByte(query); if (protocolVersion < 96 || protocolVersion > 111) throw Error("invalid negentropy protocol version byte"); if (protocolVersion !== PROTOCOL_VERSION) { throw Error("unsupported negentropy protocol version requested: " + (protocolVersion - 96)); } let storageSize = this.storage.size(); let prevBound = this._bound(0); let prevIndex = 0; let skip = false; while (query.length !== 0) { let o = new WrappedBuffer(); let doSkip = () => { if (skip) { skip = false; o.extend(this.encodeBound(prevBound)); o.extend(encodeVarInt(Mode.Skip)); } }; let currBound = this.decodeBound(query); let mode = decodeVarInt(query); let lower = prevIndex; let upper = this.storage.findLowerBound(prevIndex, storageSize, currBound); if (mode === Mode.Skip) { skip = true; } else if (mode === Mode.Fingerprint) { let theirFingerprint = getBytes(query, FINGERPRINT_SIZE); let ourFingerprint = this.storage.fingerprint(lower, upper); if (compareUint8Array(theirFingerprint, ourFingerprint) !== 0) { doSkip(); this.splitRange(lower, upper, currBound, o); } else { skip = true; } } else if (mode === Mode.IdList) { let numIds = decodeVarInt(query); let theirElems = {}; for (let i2 = 0; i2 < numIds; i2++) { let e = getBytes(query, ID_SIZE); theirElems[bytesToHex(e)] = e; } skip = true; this.storage.iterate(lower, upper, (item) => { let k = item.id; const id = bytesToHex(k); if (!theirElems[id]) { onhave?.(id); } else { delete theirElems[bytesToHex(k)]; } return true; }); if (onneed) { for (let v of Object.values(theirElems)) { onneed(bytesToHex(v)); } } } else { throw Error("unexpected mode"); } if (this.exceededFrameSizeLimit(fullOutput.length + o.length)) { let remainingFingerprint = this.storage.fingerprint(upper, storageSize); fullOutput.extend(this.encodeBound(this._bound(Number.MAX_VALUE))); fullOutput.extend(encodeVarInt(Mode.Fingerprint)); fullOutput.extend(remainingFingerprint); break; } else { fullOutput.extend(o); } prevIndex = upper; prevBound = currBound; } return fullOutput.length === 1 ? null : bytesToHex(fullOutput.unwrap()); } splitRange(lower, upper, upperBound, o) { let numElems = upper - lower; let buckets = 16; if (numElems < buckets * 2) { o.extend(this.encodeBound(upperBound)); o.extend(encodeVarInt(Mode.IdList)); o.extend(encodeVarInt(numElems)); this.storage.iterate(lower, upper, (item) => { o.extend(item.id); return true; }); } else { let itemsPerBucket = Math.floor(numElems / buckets); let bucketsWithExtra = numElems % buckets; let curr = lower; for (let i2 = 0; i2 < buckets; i2++) { let bucketSize = itemsPerBucket + (i2 < bucketsWithExtra ? 1 : 0); let ourFingerprint = this.storage.fingerprint(curr, curr + bucketSize); curr += bucketSize; let nextBound; if (curr === upper) { nextBound = upperBound; } else { let prevItem; let currItem; this.storage.iterate(curr - 1, curr + 1, (item, index) => { if (index === curr - 1) prevItem = item; else currItem = item; return true; }); nextBound = this.getMinimalBound(prevItem, currItem); } o.extend(this.encodeBound(nextBound)); o.extend(encodeVarInt(Mode.Fingerprint)); o.extend(ourFingerprint); } } } exceededFrameSizeLimit(n) { return n > this.frameSizeLimit - 200; } decodeTimestampIn(encoded) { let timestamp = decodeVarInt(encoded); timestamp = timestamp === 0 ? Number.MAX_VALUE : timestamp - 1; if (this.lastTimestampIn === Number.MAX_VALUE || timestamp === Number.MAX_VALUE) { this.lastTimestampIn = Number.MAX_VALUE; return Number.MAX_VALUE; } timestamp += this.lastTimestampIn; this.lastTimestampIn = timestamp; return timestamp; } decodeBound(encoded) { let timestamp = this.decodeTimestampIn(encoded); let len = decodeVarInt(encoded); if (len > ID_SIZE) throw Error("bound key too long"); let id = getBytes(encoded, len); return { timestamp, id }; } encodeTimestampOut(timestamp) { if (timestamp === Number.MAX_VALUE) { this.lastTimestampOut = Number.MAX_VALUE; return encodeVarInt(0); } let temp = timestamp; timestamp -= this.lastTimestampOut; this.lastTimestampOut = temp; return encodeVarInt(timestamp + 1); } encodeBound(key) { let output = new WrappedBuffer(); output.extend(this.encodeTimestampOut(key.timestamp)); output.extend(encodeVarInt(key.id.length)); output.extend(key.id); return output; } getMinimalBound(prev, curr) { if (curr.timestamp !== prev.timestamp) { return this._bound(curr.timestamp); } else { let sharedPrefixBytes = 0; let currKey = curr.id; let prevKey = prev.id; for (let i2 = 0; i2 < ID_SIZE; i2++) { if (currKey[i2] !== prevKey[i2]) break; sharedPrefixBytes++; } return this._bound(curr.timestamp, curr.id.subarray(0, sharedPrefixBytes + 1)); } } }; function compareUint8Array(a, b) { for (let i2 = 0; i2 < a.byteLength; i2++) { if (a[i2] < b[i2]) return -1; if (a[i2] > b[i2]) return 1; } if (a.byteLength > b.byteLength) return 1; if (a.byteLength < b.byteLength) return -1; return 0; } function itemCompare(a, b) { if (a.timestamp === b.timestamp) { return compareUint8Array(a.id, b.id); } return a.timestamp - b.timestamp; } var NegentropySync = class { relay; storage; neg; filter; subscription; onhave; onneed; constructor(relay, storage, filter, params = {}) { this.relay = relay; this.storage = storage; this.neg = new Negentropy(storage); this.onhave = params.onhave; this.onneed = params.onneed; this.filter = filter; this.subscription = this.relay.prepareSubscription([{}], { label: params.label || "negentropy" }); this.subscription.oncustom = (data) => { switch (data[0]) { case "NEG-MSG": { if (data.length < 3) { console.warn(`got invalid NEG-MSG from ${this.relay.url}: ${data}`); } try { const response = this.neg.reconcile(data[2], this.onhave, this.onneed); if (response) { this.relay.send(`["NEG-MSG", "${this.subscription.id}", "${response}"]`); } else { this.close(); params.onclose?.(); } } catch (error) { console.error("negentropy reconcile error:", error); params?.onclose?.(`reconcile error: ${error}`); } break; } case "NEG-CLOSE": { const reason = data[2]; console.warn("negentropy error:", reason); params.onclose?.(reason); break; } case "NEG-ERR": { params.onclose?.(); } } }; } async start() { const initMsg = this.neg.initiate(); this.relay.send(`["NEG-OPEN","${this.subscription.id}",${JSON.stringify(this.filter)},"${initMsg}"]`); } close() { this.relay.send(`["NEG-CLOSE","${this.subscription.id}"]`); this.subscription.close(); } }; // nip98.ts var nip98_exports = {}; __export(nip98_exports, { getToken: () => getToken, hashPayload: () => hashPayload, unpackEventFromToken: () => unpackEventFromToken, validateEvent: () => validateEvent2, validateEventKind: () => validateEventKind, validateEventMethodTag: () => validateEventMethodTag, validateEventPayloadTag: () => validateEventPayloadTag, validateEventTimestamp: () => validateEventTimestamp, validateEventUrlTag: () => validateEventUrlTag, validateToken: () => validateToken }); var _authorizationScheme = "Nostr "; async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false, payload) { const event = { kind: HTTPAuth, tags: [ ["u", loginUrl], ["method", httpMethod] ], created_at: Math.round(new Date().getTime() / 1e3), content: "" }; if (payload) { event.tags.push(["payload", hashPayload(payload)]); } const signedEvent = await sign(event); const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : ""; return authorizationScheme + base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent))); } async function validateToken(token, url, method) { const event = await unpackEventFromToken(token).catch((error) => { throw error; }); const valid = await validateEvent2(event, url, method).catch((error) => { throw error; }); return valid; } async function unpackEventFromToken(token) { if (!token) { throw new Error("Missing token"); } token = token.replace(_authorizationScheme, ""); const eventB64 = utf8Decoder.decode(base64.decode(token)); if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) { throw new Error("Invalid token"); } const event = JSON.parse(eventB64); return event; } function validateEventTimestamp(event) { if (!event.created_at) { return false; } return Math.round(new Date().getTime() / 1e3) - event.created_at < 60; } function validateEventKind(event) { return event.kind === HTTPAuth; } function validateEventUrlTag(event, url) { const urlTag = event.tags.find((t) => t[0] === "u"); if (!urlTag) { return false; } return urlTag.length > 0 && urlTag[1] === url; } function validateEventMethodTag(event, method) { const methodTag = event.tags.find((t) => t[0] === "method"); if (!methodTag) { return false; } return methodTag.length > 0 && methodTag[1].toLowerCase() === method.toLowerCase(); } function hashPayload(payload) { const hash = sha256(utf8Encoder.encode(JSON.stringify(payload))); return bytesToHex(hash); } function validateEventPayloadTag(event, payload) { const payloadTag = event.tags.find((t) => t[0] === "payload"); if (!payloadTag) { return false; } const payloadHash = hashPayload(payload); return payloadTag.length > 0 && payloadTag[1] === payloadHash; } async function validateEvent2(event, url, method, body) { if (!verifyEvent(event)) { throw new Error("Invalid nostr event, signature invalid"); } if (!validateEventKind(event)) { throw new Error("Invalid nostr event, kind invalid"); } if (!validateEventTimestamp(event)) { throw new Error("Invalid nostr event, created_at timestamp invalid"); } if (!validateEventUrlTag(event, url)) { throw new Error("Invalid nostr event, url tag invalid"); } if (!validateEventMethodTag(event, method)) { throw new Error("Invalid nostr event, method tag invalid"); } if (Boolean(body) && typeof body === "object" && Object.keys(body).length > 0) { if (!validateEventPayloadTag(event, body)) { throw new Error("Invalid nostr event, payload tag does not match request body hash"); } } return true; } return __toCommonJS(nostr_tools_exports); })();