From 87fecfc2e30c086c345086b27bee53d98fa74030 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Thu, 26 Sep 2024 16:03:28 -0500 Subject: [PATCH] Update landing page --- .changeset/shaggy-bats-pretend.md | 5 + public/index.html | 32 +- public/lib/milligram.css | 635 +++++ public/lib/normalize.css | 349 +++ public/lib/nostr-name.js | 4034 ++++++++++++++++++++++++++++ public/lib/nostr-picture.js | 4050 +++++++++++++++++++++++++++++ public/logo.jpg | Bin 0 -> 45294 bytes public/main.js | 25 +- 8 files changed, 9111 insertions(+), 19 deletions(-) create mode 100644 .changeset/shaggy-bats-pretend.md create mode 100644 public/lib/milligram.css create mode 100644 public/lib/normalize.css create mode 100644 public/lib/nostr-name.js create mode 100644 public/lib/nostr-picture.js create mode 100644 public/logo.jpg diff --git a/.changeset/shaggy-bats-pretend.md b/.changeset/shaggy-bats-pretend.md new file mode 100644 index 0000000..2313efd --- /dev/null +++ b/.changeset/shaggy-bats-pretend.md @@ -0,0 +1,5 @@ +--- +"nsite-ts": patch +--- + +Update landing page diff --git a/public/index.html b/public/index.html index ac75cae..3615823 100644 --- a/public/index.html +++ b/public/index.html @@ -4,6 +4,12 @@ nsite + + + + + + + + -

nsite-ts

- Source Code +
+ +

nsite

+ Source Code -

Latest nsites:

-
+

Latest nsites:

+
+
diff --git a/public/lib/milligram.css b/public/lib/milligram.css new file mode 100644 index 0000000..8118dee --- /dev/null +++ b/public/lib/milligram.css @@ -0,0 +1,635 @@ +/*! + * Milligram v1.4.1 + * https://milligram.io + * + * Copyright (c) 2020 CJ Patoilo + * Licensed under the MIT license + */ + +*, +*:after, +*:before { + box-sizing: inherit; +} + +html { + box-sizing: border-box; + font-size: 62.5%; +} + +body { + color: #606c76; + font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + font-size: 1.6em; + font-weight: 300; + letter-spacing: .01em; + line-height: 1.6; +} + +blockquote { + border-left: 0.3rem solid #d1d1d1; + margin-left: 0; + margin-right: 0; + padding: 1rem 1.5rem; +} + +blockquote *:last-child { + margin-bottom: 0; +} + +.button, +button, +input[type='button'], +input[type='reset'], +input[type='submit'] { + background-color: #9b4dca; + border: 0.1rem solid #9b4dca; + border-radius: .4rem; + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 1.1rem; + font-weight: 700; + height: 3.8rem; + letter-spacing: .1rem; + line-height: 3.8rem; + padding: 0 3.0rem; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; +} + +.button:focus, .button:hover, +button:focus, +button:hover, +input[type='button']:focus, +input[type='button']:hover, +input[type='reset']:focus, +input[type='reset']:hover, +input[type='submit']:focus, +input[type='submit']:hover { + background-color: #606c76; + border-color: #606c76; + color: #fff; + outline: 0; +} + +.button[disabled], +button[disabled], +input[type='button'][disabled], +input[type='reset'][disabled], +input[type='submit'][disabled] { + cursor: default; + opacity: .5; +} + +.button[disabled]:focus, .button[disabled]:hover, +button[disabled]:focus, +button[disabled]:hover, +input[type='button'][disabled]:focus, +input[type='button'][disabled]:hover, +input[type='reset'][disabled]:focus, +input[type='reset'][disabled]:hover, +input[type='submit'][disabled]:focus, +input[type='submit'][disabled]:hover { + background-color: #9b4dca; + border-color: #9b4dca; +} + +.button.button-outline, +button.button-outline, +input[type='button'].button-outline, +input[type='reset'].button-outline, +input[type='submit'].button-outline { + background-color: transparent; + color: #9b4dca; +} + +.button.button-outline:focus, .button.button-outline:hover, +button.button-outline:focus, +button.button-outline:hover, +input[type='button'].button-outline:focus, +input[type='button'].button-outline:hover, +input[type='reset'].button-outline:focus, +input[type='reset'].button-outline:hover, +input[type='submit'].button-outline:focus, +input[type='submit'].button-outline:hover { + background-color: transparent; + border-color: #606c76; + color: #606c76; +} + +.button.button-outline[disabled]:focus, .button.button-outline[disabled]:hover, +button.button-outline[disabled]:focus, +button.button-outline[disabled]:hover, +input[type='button'].button-outline[disabled]:focus, +input[type='button'].button-outline[disabled]:hover, +input[type='reset'].button-outline[disabled]:focus, +input[type='reset'].button-outline[disabled]:hover, +input[type='submit'].button-outline[disabled]:focus, +input[type='submit'].button-outline[disabled]:hover { + border-color: inherit; + color: #9b4dca; +} + +.button.button-clear, +button.button-clear, +input[type='button'].button-clear, +input[type='reset'].button-clear, +input[type='submit'].button-clear { + background-color: transparent; + border-color: transparent; + color: #9b4dca; +} + +.button.button-clear:focus, .button.button-clear:hover, +button.button-clear:focus, +button.button-clear:hover, +input[type='button'].button-clear:focus, +input[type='button'].button-clear:hover, +input[type='reset'].button-clear:focus, +input[type='reset'].button-clear:hover, +input[type='submit'].button-clear:focus, +input[type='submit'].button-clear:hover { + background-color: transparent; + border-color: transparent; + color: #606c76; +} + +.button.button-clear[disabled]:focus, .button.button-clear[disabled]:hover, +button.button-clear[disabled]:focus, +button.button-clear[disabled]:hover, +input[type='button'].button-clear[disabled]:focus, +input[type='button'].button-clear[disabled]:hover, +input[type='reset'].button-clear[disabled]:focus, +input[type='reset'].button-clear[disabled]:hover, +input[type='submit'].button-clear[disabled]:focus, +input[type='submit'].button-clear[disabled]:hover { + color: #9b4dca; +} + +code { + background: #f4f5f6; + border-radius: .4rem; + font-size: 86%; + margin: 0 .2rem; + padding: .2rem .5rem; + white-space: nowrap; +} + +pre { + background: #f4f5f6; + border-left: 0.3rem solid #9b4dca; + overflow-y: hidden; +} + +pre > code { + border-radius: 0; + display: block; + padding: 1rem 1.5rem; + white-space: pre; +} + +hr { + border: 0; + border-top: 0.1rem solid #f4f5f6; + margin: 3.0rem 0; +} + +input[type='color'], +input[type='date'], +input[type='datetime'], +input[type='datetime-local'], +input[type='email'], +input[type='month'], +input[type='number'], +input[type='password'], +input[type='search'], +input[type='tel'], +input[type='text'], +input[type='url'], +input[type='week'], +input:not([type]), +textarea, +select { + -webkit-appearance: none; + background-color: transparent; + border: 0.1rem solid #d1d1d1; + border-radius: .4rem; + box-shadow: none; + box-sizing: inherit; + height: 3.8rem; + padding: .6rem 1.0rem .7rem; + width: 100%; +} + +input[type='color']:focus, +input[type='date']:focus, +input[type='datetime']:focus, +input[type='datetime-local']:focus, +input[type='email']:focus, +input[type='month']:focus, +input[type='number']:focus, +input[type='password']:focus, +input[type='search']:focus, +input[type='tel']:focus, +input[type='text']:focus, +input[type='url']:focus, +input[type='week']:focus, +input:not([type]):focus, +textarea:focus, +select:focus { + border-color: #9b4dca; + outline: 0; +} + +select { + background: url('data:image/svg+xml;utf8,') center right no-repeat; + padding-right: 3.0rem; +} + +select:focus { + background-image: url('data:image/svg+xml;utf8,'); +} + +select[multiple] { + background: none; + height: auto; +} + +textarea { + min-height: 6.5rem; +} + +label, +legend { + display: block; + font-size: 1.6rem; + font-weight: 700; + margin-bottom: .5rem; +} + +fieldset { + border-width: 0; + padding: 0; +} + +input[type='checkbox'], +input[type='radio'] { + display: inline; +} + +.label-inline { + display: inline-block; + font-weight: normal; + margin-left: .5rem; +} + +.container { + margin: 0 auto; + max-width: 112.0rem; + padding: 0 2.0rem; + position: relative; + width: 100%; +} + +.row { + display: flex; + flex-direction: column; + padding: 0; + width: 100%; +} + +.row.row-no-padding { + padding: 0; +} + +.row.row-no-padding > .column { + padding: 0; +} + +.row.row-wrap { + flex-wrap: wrap; +} + +.row.row-top { + align-items: flex-start; +} + +.row.row-bottom { + align-items: flex-end; +} + +.row.row-center { + align-items: center; +} + +.row.row-stretch { + align-items: stretch; +} + +.row.row-baseline { + align-items: baseline; +} + +.row .column { + display: block; + flex: 1 1 auto; + margin-left: 0; + max-width: 100%; + width: 100%; +} + +.row .column.column-offset-10 { + margin-left: 10%; +} + +.row .column.column-offset-20 { + margin-left: 20%; +} + +.row .column.column-offset-25 { + margin-left: 25%; +} + +.row .column.column-offset-33, .row .column.column-offset-34 { + margin-left: 33.3333%; +} + +.row .column.column-offset-40 { + margin-left: 40%; +} + +.row .column.column-offset-50 { + margin-left: 50%; +} + +.row .column.column-offset-60 { + margin-left: 60%; +} + +.row .column.column-offset-66, .row .column.column-offset-67 { + margin-left: 66.6666%; +} + +.row .column.column-offset-75 { + margin-left: 75%; +} + +.row .column.column-offset-80 { + margin-left: 80%; +} + +.row .column.column-offset-90 { + margin-left: 90%; +} + +.row .column.column-10 { + flex: 0 0 10%; + max-width: 10%; +} + +.row .column.column-20 { + flex: 0 0 20%; + max-width: 20%; +} + +.row .column.column-25 { + flex: 0 0 25%; + max-width: 25%; +} + +.row .column.column-33, .row .column.column-34 { + flex: 0 0 33.3333%; + max-width: 33.3333%; +} + +.row .column.column-40 { + flex: 0 0 40%; + max-width: 40%; +} + +.row .column.column-50 { + flex: 0 0 50%; + max-width: 50%; +} + +.row .column.column-60 { + flex: 0 0 60%; + max-width: 60%; +} + +.row .column.column-66, .row .column.column-67 { + flex: 0 0 66.6666%; + max-width: 66.6666%; +} + +.row .column.column-75 { + flex: 0 0 75%; + max-width: 75%; +} + +.row .column.column-80 { + flex: 0 0 80%; + max-width: 80%; +} + +.row .column.column-90 { + flex: 0 0 90%; + max-width: 90%; +} + +.row .column .column-top { + align-self: flex-start; +} + +.row .column .column-bottom { + align-self: flex-end; +} + +.row .column .column-center { + align-self: center; +} + +@media (min-width: 40rem) { + .row { + flex-direction: row; + margin-left: -1.0rem; + width: calc(100% + 2.0rem); + } + .row .column { + margin-bottom: inherit; + padding: 0 1.0rem; + } +} + +a { + color: #9b4dca; + text-decoration: none; +} + +a:focus, a:hover { + color: #606c76; +} + +dl, +ol, +ul { + list-style: none; + margin-top: 0; + padding-left: 0; +} + +dl dl, +dl ol, +dl ul, +ol dl, +ol ol, +ol ul, +ul dl, +ul ol, +ul ul { + font-size: 90%; + margin: 1.5rem 0 1.5rem 3.0rem; +} + +ol { + list-style: decimal inside; +} + +ul { + list-style: circle inside; +} + +.button, +button, +dd, +dt, +li { + margin-bottom: 1.0rem; +} + +fieldset, +input, +select, +textarea { + margin-bottom: 1.5rem; +} + +blockquote, +dl, +figure, +form, +ol, +p, +pre, +table, +ul { + margin-bottom: 2.5rem; +} + +table { + border-spacing: 0; + display: block; + overflow-x: auto; + text-align: left; + width: 100%; +} + +td, +th { + border-bottom: 0.1rem solid #e1e1e1; + padding: 1.2rem 1.5rem; +} + +td:first-child, +th:first-child { + padding-left: 0; +} + +td:last-child, +th:last-child { + padding-right: 0; +} + +@media (min-width: 40rem) { + table { + display: table; + overflow-x: initial; + } +} + +b, +strong { + font-weight: bold; +} + +p { + margin-top: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; + letter-spacing: -.1rem; + margin-bottom: 2.0rem; + margin-top: 0; +} + +h1 { + font-size: 4.6rem; + line-height: 1.2; +} + +h2 { + font-size: 3.6rem; + line-height: 1.25; +} + +h3 { + font-size: 2.8rem; + line-height: 1.3; +} + +h4 { + font-size: 2.2rem; + letter-spacing: -.08rem; + line-height: 1.35; +} + +h5 { + font-size: 1.8rem; + letter-spacing: -.05rem; + line-height: 1.5; +} + +h6 { + font-size: 1.6rem; + letter-spacing: 0; + line-height: 1.4; +} + +img { + max-width: 100%; +} + +.clearfix:after { + clear: both; + content: ' '; + display: table; +} + +.float-left { + float: left; +} + +.float-right { + float: right; +} + +/*# sourceMappingURL=milligram.css.map */ \ No newline at end of file diff --git a/public/lib/normalize.css b/public/lib/normalize.css new file mode 100644 index 0000000..192eb9c --- /dev/null +++ b/public/lib/normalize.css @@ -0,0 +1,349 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/public/lib/nostr-name.js b/public/lib/nostr-name.js new file mode 100644 index 0000000..8573999 --- /dev/null +++ b/public/lib/nostr-name.js @@ -0,0 +1,4034 @@ +"use strict"; +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __commonJS = (cb, mod2) => function __require() { + return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; + }; + 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 __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( + isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, + mod2 + )); + var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; + }; + + // node_modules/obliterator/iterator.js + var require_iterator = __commonJS({ + "node_modules/obliterator/iterator.js"(exports, module) { + function Iterator(next) { + if (typeof next !== "function") + throw new Error("obliterator/iterator: expecting a function!"); + this.next = next; + } + if (typeof Symbol !== "undefined") + Iterator.prototype[Symbol.iterator] = function() { + return this; + }; + Iterator.of = function() { + var args = arguments, l = args.length, i2 = 0; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + return { done: false, value: args[i2++] }; + }); + }; + Iterator.empty = function() { + var iterator = new Iterator(function() { + return { done: true }; + }); + return iterator; + }; + Iterator.fromSequence = function(sequence) { + var i2 = 0, l = sequence.length; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + return { done: false, value: sequence[i2++] }; + }); + }; + Iterator.is = function(value) { + if (value instanceof Iterator) + return true; + return typeof value === "object" && value !== null && typeof value.next === "function"; + }; + module.exports = Iterator; + } + }); + + // node_modules/obliterator/support.js + var require_support = __commonJS({ + "node_modules/obliterator/support.js"(exports) { + exports.ARRAY_BUFFER_SUPPORT = typeof ArrayBuffer !== "undefined"; + exports.SYMBOL_SUPPORT = typeof Symbol !== "undefined"; + } + }); + + // node_modules/obliterator/foreach.js + var require_foreach = __commonJS({ + "node_modules/obliterator/foreach.js"(exports, module) { + var support = require_support(); + var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; + var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; + module.exports = function forEach(iterable, callback) { + var iterator, k, i2, l, s; + if (!iterable) + throw new Error("obliterator/forEach: invalid iterable."); + if (typeof callback !== "function") + throw new Error("obliterator/forEach: expecting a callback."); + if (Array.isArray(iterable) || ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(iterable) || typeof iterable === "string" || iterable.toString() === "[object Arguments]") { + for (i2 = 0, l = iterable.length; i2 < l; i2++) + callback(iterable[i2], i2); + return; + } + if (typeof iterable.forEach === "function") { + iterable.forEach(callback); + return; + } + if (SYMBOL_SUPPORT && Symbol.iterator in iterable && typeof iterable.next !== "function") { + iterable = iterable[Symbol.iterator](); + } + if (typeof iterable.next === "function") { + iterator = iterable; + i2 = 0; + while (s = iterator.next(), s.done !== true) { + callback(s.value, i2); + i2++; + } + return; + } + for (k in iterable) { + if (iterable.hasOwnProperty(k)) { + callback(iterable[k], k); + } + } + return; + }; + } + }); + + // node_modules/mnemonist/utils/typed-arrays.js + var require_typed_arrays = __commonJS({ + "node_modules/mnemonist/utils/typed-arrays.js"(exports) { + var MAX_8BIT_INTEGER = Math.pow(2, 8) - 1; + var MAX_16BIT_INTEGER = Math.pow(2, 16) - 1; + var MAX_32BIT_INTEGER = Math.pow(2, 32) - 1; + var MAX_SIGNED_8BIT_INTEGER = Math.pow(2, 7) - 1; + var MAX_SIGNED_16BIT_INTEGER = Math.pow(2, 15) - 1; + var MAX_SIGNED_32BIT_INTEGER = Math.pow(2, 31) - 1; + exports.getPointerArray = function(size) { + var maxIndex = size - 1; + if (maxIndex <= MAX_8BIT_INTEGER) + return Uint8Array; + if (maxIndex <= MAX_16BIT_INTEGER) + return Uint16Array; + if (maxIndex <= MAX_32BIT_INTEGER) + return Uint32Array; + throw new Error("mnemonist: Pointer Array of size > 4294967295 is not supported."); + }; + exports.getSignedPointerArray = function(size) { + var maxIndex = size - 1; + if (maxIndex <= MAX_SIGNED_8BIT_INTEGER) + return Int8Array; + if (maxIndex <= MAX_SIGNED_16BIT_INTEGER) + return Int16Array; + if (maxIndex <= MAX_SIGNED_32BIT_INTEGER) + return Int32Array; + return Float64Array; + }; + exports.getNumberType = function(value) { + if (value === (value | 0)) { + if (Math.sign(value) === -1) { + if (value <= 127 && value >= -128) + return Int8Array; + if (value <= 32767 && value >= -32768) + return Int16Array; + return Int32Array; + } else { + if (value <= 255) + return Uint8Array; + if (value <= 65535) + return Uint16Array; + return Uint32Array; + } + } + return Float64Array; + }; + var TYPE_PRIORITY = { + Uint8Array: 1, + Int8Array: 2, + Uint16Array: 3, + Int16Array: 4, + Uint32Array: 5, + Int32Array: 6, + Float32Array: 7, + Float64Array: 8 + }; + exports.getMinimalRepresentation = function(array, getter) { + var maxType = null, maxPriority = 0, p, t, v, i2, l; + for (i2 = 0, l = array.length; i2 < l; i2++) { + v = getter ? getter(array[i2]) : array[i2]; + t = exports.getNumberType(v); + p = TYPE_PRIORITY[t.name]; + if (p > maxPriority) { + maxPriority = p; + maxType = t; + } + } + return maxType; + }; + exports.isTypedArray = function(value) { + return typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(value); + }; + exports.concat = function() { + var length = 0, i2, o, l; + for (i2 = 0, l = arguments.length; i2 < l; i2++) + length += arguments[i2].length; + var array = new arguments[0].constructor(length); + for (i2 = 0, o = 0; i2 < l; i2++) { + array.set(arguments[i2], o); + o += arguments[i2].length; + } + return array; + }; + exports.indices = function(length) { + var PointerArray = exports.getPointerArray(length); + var array = new PointerArray(length); + for (var i2 = 0; i2 < length; i2++) + array[i2] = i2; + return array; + }; + } + }); + + // node_modules/mnemonist/utils/iterables.js + var require_iterables = __commonJS({ + "node_modules/mnemonist/utils/iterables.js"(exports) { + var forEach = require_foreach(); + var typed = require_typed_arrays(); + function isArrayLike(target) { + return Array.isArray(target) || typed.isTypedArray(target); + } + function guessLength(target) { + if (typeof target.length === "number") + return target.length; + if (typeof target.size === "number") + return target.size; + return; + } + function toArray(target) { + var l = guessLength(target); + var array = typeof l === "number" ? new Array(l) : []; + var i2 = 0; + forEach(target, function(value) { + array[i2++] = value; + }); + return array; + } + function toArrayWithIndices(target) { + var l = guessLength(target); + var IndexArray = typeof l === "number" ? typed.getPointerArray(l) : Array; + var array = typeof l === "number" ? new Array(l) : []; + var indices = typeof l === "number" ? new IndexArray(l) : []; + var i2 = 0; + forEach(target, function(value) { + array[i2] = value; + indices[i2] = i2++; + }); + return [array, indices]; + } + exports.isArrayLike = isArrayLike; + exports.guessLength = guessLength; + exports.toArray = toArray; + exports.toArrayWithIndices = toArrayWithIndices; + } + }); + + // node_modules/mnemonist/lru-cache.js + var require_lru_cache = __commonJS({ + "node_modules/mnemonist/lru-cache.js"(exports, module) { + var Iterator = require_iterator(); + var forEach = require_foreach(); + var typed = require_typed_arrays(); + var iterables = require_iterables(); + function LRUCache2(Keys, Values, capacity) { + if (arguments.length < 2) { + capacity = Keys; + Keys = null; + Values = null; + } + this.capacity = capacity; + if (typeof this.capacity !== "number" || this.capacity <= 0) + throw new Error("mnemonist/lru-cache: capacity should be positive number."); + else if (!isFinite(this.capacity) || Math.floor(this.capacity) !== this.capacity) + throw new Error("mnemonist/lru-cache: capacity should be a finite positive integer."); + var PointerArray = typed.getPointerArray(capacity); + this.forward = new PointerArray(capacity); + this.backward = new PointerArray(capacity); + this.K = typeof Keys === "function" ? new Keys(capacity) : new Array(capacity); + this.V = typeof Values === "function" ? new Values(capacity) : new Array(capacity); + this.size = 0; + this.head = 0; + this.tail = 0; + this.items = {}; + } + LRUCache2.prototype.clear = function() { + this.size = 0; + this.head = 0; + this.tail = 0; + this.items = {}; + }; + LRUCache2.prototype.splayOnTop = function(pointer) { + var oldHead = this.head; + if (this.head === pointer) + return this; + var previous = this.backward[pointer], next = this.forward[pointer]; + if (this.tail === pointer) { + this.tail = previous; + } else { + this.backward[next] = previous; + } + this.forward[previous] = next; + this.backward[oldHead] = pointer; + this.head = pointer; + this.forward[pointer] = oldHead; + return this; + }; + LRUCache2.prototype.set = function(key, value) { + var pointer = this.items[key]; + if (typeof pointer !== "undefined") { + this.splayOnTop(pointer); + this.V[pointer] = value; + return; + } + if (this.size < this.capacity) { + pointer = this.size++; + } else { + pointer = this.tail; + this.tail = this.backward[pointer]; + delete this.items[this.K[pointer]]; + } + this.items[key] = pointer; + this.K[pointer] = key; + this.V[pointer] = value; + this.forward[pointer] = this.head; + this.backward[this.head] = pointer; + this.head = pointer; + }; + LRUCache2.prototype.setpop = function(key, value) { + var oldValue = null; + var oldKey = null; + var pointer = this.items[key]; + if (typeof pointer !== "undefined") { + this.splayOnTop(pointer); + oldValue = this.V[pointer]; + this.V[pointer] = value; + return { evicted: false, key, value: oldValue }; + } + if (this.size < this.capacity) { + pointer = this.size++; + } else { + pointer = this.tail; + this.tail = this.backward[pointer]; + oldValue = this.V[pointer]; + oldKey = this.K[pointer]; + delete this.items[oldKey]; + } + this.items[key] = pointer; + this.K[pointer] = key; + this.V[pointer] = value; + this.forward[pointer] = this.head; + this.backward[this.head] = pointer; + this.head = pointer; + if (oldKey) { + return { evicted: true, key: oldKey, value: oldValue }; + } else { + return null; + } + }; + LRUCache2.prototype.has = function(key) { + return key in this.items; + }; + LRUCache2.prototype.get = function(key) { + var pointer = this.items[key]; + if (typeof pointer === "undefined") + return; + this.splayOnTop(pointer); + return this.V[pointer]; + }; + LRUCache2.prototype.peek = function(key) { + var pointer = this.items[key]; + if (typeof pointer === "undefined") + return; + return this.V[pointer]; + }; + LRUCache2.prototype.forEach = function(callback, scope) { + scope = arguments.length > 1 ? scope : this; + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, values = this.V, forward = this.forward; + while (i2 < l) { + callback.call(scope, values[pointer], keys[pointer], this); + pointer = forward[pointer]; + i2++; + } + }; + LRUCache2.prototype.keys = function() { + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var key = keys[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value: key + }; + }); + }; + LRUCache2.prototype.values = function() { + var i2 = 0, l = this.size; + var pointer = this.head, values = this.V, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var value = values[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value + }; + }); + }; + LRUCache2.prototype.entries = function() { + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, values = this.V, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var key = keys[pointer], value = values[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value: [key, value] + }; + }); + }; + if (typeof Symbol !== "undefined") + LRUCache2.prototype[Symbol.iterator] = LRUCache2.prototype.entries; + LRUCache2.prototype.inspect = function() { + var proxy = /* @__PURE__ */ new Map(); + var iterator = this.entries(), step; + while (step = iterator.next(), !step.done) + proxy.set(step.value[0], step.value[1]); + Object.defineProperty(proxy, "constructor", { + value: LRUCache2, + enumerable: false + }); + return proxy; + }; + if (typeof Symbol !== "undefined") + LRUCache2.prototype[Symbol.for("nodejs.util.inspect.custom")] = LRUCache2.prototype.inspect; + LRUCache2.from = function(iterable, Keys, Values, capacity) { + if (arguments.length < 2) { + capacity = iterables.guessLength(iterable); + if (typeof capacity !== "number") + throw new Error("mnemonist/lru-cache.from: could not guess iterable length. Please provide desired capacity as last argument."); + } else if (arguments.length === 2) { + capacity = Keys; + Keys = null; + Values = null; + } + var cache = new LRUCache2(Keys, Values, capacity); + forEach(iterable, function(value, key) { + cache.set(key, value); + }); + return cache; + }; + module.exports = LRUCache2; + } + }); + + // node_modules/debounce/index.js + var require_debounce = __commonJS({ + "node_modules/debounce/index.js"(exports, module) { + function debounce2(function_, wait = 100, options = {}) { + if (typeof function_ !== "function") { + throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`); + } + if (wait < 0) { + throw new RangeError("`wait` must not be negative."); + } + const { immediate } = typeof options === "boolean" ? { immediate: options } : options; + let storedContext; + let storedArguments; + let timeoutId; + let timestamp; + let result; + function run() { + const callContext = storedContext; + const callArguments = storedArguments; + storedContext = void 0; + storedArguments = void 0; + result = function_.apply(callContext, callArguments); + return result; + } + function later() { + const last = Date.now() - timestamp; + if (last < wait && last >= 0) { + timeoutId = setTimeout(later, wait - last); + } else { + timeoutId = void 0; + if (!immediate) { + result = run(); + } + } + } + const debounced = function(...arguments_) { + if (storedContext && this !== storedContext) { + throw new Error("Debounced method called with different contexts."); + } + storedContext = this; + storedArguments = arguments_; + timestamp = Date.now(); + const callNow = immediate && !timeoutId; + if (!timeoutId) { + timeoutId = setTimeout(later, wait); + } + if (callNow) { + result = run(); + } + return result; + }; + debounced.clear = () => { + if (!timeoutId) { + return; + } + clearTimeout(timeoutId); + timeoutId = void 0; + }; + debounced.flush = () => { + if (!timeoutId) { + return; + } + debounced.trigger(); + }; + debounced.trigger = () => { + result = run(); + debounced.clear(); + }; + return debounced; + } + module.exports.debounce = debounce2; + module.exports = debounce2; + } + }); + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/_assert.js + function number(n) { + if (!Number.isSafeInteger(n) || n < 0) + throw new Error(`Wrong positive integer: ${n}`); + } + function bytes(b, ...lengths) { + if (!(b instanceof Uint8Array)) + throw new Error("Expected Uint8Array"); + if (lengths.length > 0 && !lengths.includes(b.length)) + throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`); + } + function hash(hash3) { + if (typeof hash3 !== "function" || typeof hash3.create !== "function") + throw new Error("Hash should be wrapped by utils.wrapConstructor"); + number(hash3.outputLen); + number(hash3.blockLen); + } + function exists(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 output(out, instance) { + bytes(out); + const min = instance.outputLen; + if (out.length < min) { + throw new Error(`digestInto() expects output buffer of length at least ${min}`); + } + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/crypto.js + var crypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0; + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/utils.js + var u8a = (a) => a instanceof Uint8Array; + var createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); + var rotr = (word, shift) => word << 32 - shift | word >>> shift; + var isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68; + if (!isLE) + throw new Error("Non little-endian hardware is not supported"); + function utf8ToBytes(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function toBytes(data) { + if (typeof data === "string") + data = utf8ToBytes(data); + if (!u8a(data)) + throw new Error(`expected Uint8Array, got ${typeof data}`); + return data; + } + function concatBytes(...arrays) { + const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0)); + let pad = 0; + arrays.forEach((a) => { + if (!u8a(a)) + throw new Error("Uint8Array expected"); + r.set(a, pad); + pad += a.length; + }); + return r; + } + var Hash = class { + clone() { + return this._cloneInto(); + } + }; + var toStr = {}.toString; + function wrapConstructor(hashCons) { + const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); + const tmp = hashCons(); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = () => hashCons(); + return hashC; + } + function randomBytes(bytesLength = 32) { + if (crypto && typeof crypto.getRandomValues === "function") { + return crypto.getRandomValues(new Uint8Array(bytesLength)); + } + throw new Error("crypto.getRandomValues must be defined"); + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/_sha2.js + function setBigUint64(view, byteOffset, value, isLE3) { + if (typeof view.setBigUint64 === "function") + return view.setBigUint64(byteOffset, value, isLE3); + const _32n = BigInt(32); + const _u32_max = BigInt(4294967295); + const wh = Number(value >> _32n & _u32_max); + const wl = Number(value & _u32_max); + const h = isLE3 ? 4 : 0; + const l = isLE3 ? 0 : 4; + view.setUint32(byteOffset + h, wh, isLE3); + view.setUint32(byteOffset + l, wl, isLE3); + } + var SHA2 = class extends Hash { + constructor(blockLen, outputLen, padOffset, isLE3) { + super(); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE3; + this.finished = false; + this.length = 0; + this.pos = 0; + this.destroyed = false; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + } + update(data) { + exists(this); + const { view, buffer, blockLen } = this; + data = toBytes(data); + 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) { + exists(this); + output(out, this); + this.finished = true; + const { buffer, view, blockLen, isLE: isLE3 } = this; + let { pos } = this; + buffer[pos++] = 128; + this.buffer.subarray(pos).fill(0); + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + for (let i2 = pos; i2 < blockLen; i2++) + buffer[i2] = 0; + setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE3); + this.process(view, 0); + const oview = createView(out); + const len = this.outputLen; + if (len % 4) + throw new Error("_sha2: outputLen should 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], isLE3); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to || (to = new this.constructor()); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.length = length; + to.pos = pos; + to.finished = finished; + to.destroyed = destroyed; + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + }; + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha256.js + var Chi = (a, b, c) => a & b ^ ~a & c; + var Maj = (a, b, c) => a & b ^ a & c ^ b & c; + var SHA256_K = /* @__PURE__ */ new Uint32Array([ + 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 IV = /* @__PURE__ */ new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 + ]); + var SHA256_W = /* @__PURE__ */ new Uint32Array(64); + var SHA256 = class extends SHA2 { + constructor() { + super(64, 32, 8, false); + this.A = IV[0] | 0; + this.B = IV[1] | 0; + this.C = IV[2] | 0; + this.D = IV[3] | 0; + this.E = IV[4] | 0; + this.F = IV[5] | 0; + this.G = IV[6] | 0; + this.H = IV[7] | 0; + } + 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() { + SHA256_W.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0); + this.buffer.fill(0); + } + }; + var sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256()); + + // node_modules/@noble/curves/esm/abstract/utils.js + var utils_exports = {}; + __export(utils_exports, { + bitGet: () => bitGet, + bitLen: () => bitLen, + bitMask: () => bitMask, + bitSet: () => bitSet, + bytesToHex: () => bytesToHex, + bytesToNumberBE: () => bytesToNumberBE, + bytesToNumberLE: () => bytesToNumberLE, + concatBytes: () => concatBytes2, + createHmacDrbg: () => createHmacDrbg, + ensureBytes: () => ensureBytes, + equalBytes: () => equalBytes, + hexToBytes: () => hexToBytes, + hexToNumber: () => hexToNumber, + numberToBytesBE: () => numberToBytesBE, + numberToBytesLE: () => numberToBytesLE, + numberToHexUnpadded: () => numberToHexUnpadded, + numberToVarBytesBE: () => numberToVarBytesBE, + utf8ToBytes: () => utf8ToBytes2, + validateObject: () => validateObject + }); + var _0n = BigInt(0); + var _1n = BigInt(1); + var _2n = BigInt(2); + var u8a2 = (a) => a instanceof Uint8Array; + var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i2) => i2.toString(16).padStart(2, "0")); + function bytesToHex(bytes3) { + if (!u8a2(bytes3)) + throw new Error("Uint8Array expected"); + let hex2 = ""; + for (let i2 = 0; i2 < bytes3.length; i2++) { + hex2 += hexes[bytes3[i2]]; + } + return hex2; + } + function numberToHexUnpadded(num) { + const hex2 = num.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 BigInt(hex2 === "" ? "0" : `0x${hex2}`); + } + function hexToBytes(hex2) { + if (typeof hex2 !== "string") + throw new Error("hex string expected, got " + typeof hex2); + const len = hex2.length; + if (len % 2) + throw new Error("padded hex string expected, got unpadded hex of length " + len); + const array = new Uint8Array(len / 2); + for (let i2 = 0; i2 < array.length; i2++) { + const j = i2 * 2; + const hexByte = hex2.slice(j, j + 2); + const byte = Number.parseInt(hexByte, 16); + if (Number.isNaN(byte) || byte < 0) + throw new Error("Invalid byte sequence"); + array[i2] = byte; + } + return array; + } + function bytesToNumberBE(bytes3) { + return hexToNumber(bytesToHex(bytes3)); + } + function bytesToNumberLE(bytes3) { + if (!u8a2(bytes3)) + throw new Error("Uint8Array expected"); + return hexToNumber(bytesToHex(Uint8Array.from(bytes3).reverse())); + } + function numberToBytesBE(n, len) { + return hexToBytes(n.toString(16).padStart(len * 2, "0")); + } + function numberToBytesLE(n, len) { + return numberToBytesBE(n, len).reverse(); + } + function numberToVarBytesBE(n) { + return hexToBytes(numberToHexUnpadded(n)); + } + function ensureBytes(title, hex2, expectedLength) { + let res; + if (typeof hex2 === "string") { + try { + res = hexToBytes(hex2); + } catch (e) { + throw new Error(`${title} must be valid hex string, got "${hex2}". Cause: ${e}`); + } + } else if (u8a2(hex2)) { + res = Uint8Array.from(hex2); + } else { + throw new Error(`${title} must be hex string or Uint8Array`); + } + const len = res.length; + if (typeof expectedLength === "number" && len !== expectedLength) + throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`); + return res; + } + function concatBytes2(...arrays) { + const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0)); + let pad = 0; + arrays.forEach((a) => { + if (!u8a2(a)) + throw new Error("Uint8Array expected"); + r.set(a, pad); + pad += a.length; + }); + return r; + } + function equalBytes(b1, b2) { + if (b1.length !== b2.length) + return false; + for (let i2 = 0; i2 < b1.length; i2++) + if (b1[i2] !== b2[i2]) + return false; + return true; + } + function utf8ToBytes2(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function bitLen(n) { + let len; + for (len = 0; n > _0n; n >>= _1n, len += 1) + ; + return len; + } + function bitGet(n, pos) { + return n >> BigInt(pos) & _1n; + } + var bitSet = (n, pos, value) => { + return n | (value ? _1n : _0n) << BigInt(pos); + }; + var bitMask = (n) => (_2n << BigInt(n - 1)) - _1n; + var u8n = (data) => new Uint8Array(data); + var u8fr = (arr) => Uint8Array.from(arr); + function createHmacDrbg(hashLen, qByteLen, hmacFn) { + if (typeof hashLen !== "number" || hashLen < 2) + throw new Error("hashLen must be a number"); + if (typeof qByteLen !== "number" || qByteLen < 2) + throw new Error("qByteLen must be a number"); + if (typeof hmacFn !== "function") + throw new Error("hmacFn must be a function"); + let v = u8n(hashLen); + let k = u8n(hashLen); + let i2 = 0; + const reset = () => { + v.fill(1); + k.fill(0); + i2 = 0; + }; + const h = (...b) => hmacFn(k, v, ...b); + const reseed = (seed = u8n()) => { + k = h(u8fr([0]), seed); + v = h(); + if (seed.length === 0) + return; + k = h(u8fr([1]), seed); + v = h(); + }; + const gen = () => { + if (i2++ >= 1e3) + throw new Error("drbg: tried 1000 values"); + let len = 0; + const out = []; + while (len < qByteLen) { + v = h(); + const sl = v.slice(); + out.push(sl); + len += v.length; + } + return concatBytes2(...out); + }; + const genUntil = (seed, pred) => { + reset(); + reseed(seed); + let res = void 0; + while (!(res = pred(gen()))) + reseed(); + reset(); + return res; + }; + return genUntil; + } + var validatorFns = { + bigint: (val) => typeof val === "bigint", + function: (val) => typeof val === "function", + boolean: (val) => typeof val === "boolean", + string: (val) => typeof val === "string", + stringOrUint8Array: (val) => typeof val === "string" || val instanceof Uint8Array, + isSafeInteger: (val) => Number.isSafeInteger(val), + array: (val) => Array.isArray(val), + field: (val, object) => object.Fp.isValid(val), + hash: (val) => typeof val === "function" && Number.isSafeInteger(val.outputLen) + }; + function validateObject(object, validators, optValidators = {}) { + const checkField = (fieldName, type, isOptional) => { + const checkVal = validatorFns[type]; + if (typeof checkVal !== "function") + throw new Error(`Invalid validator "${type}", expected function`); + const val = object[fieldName]; + if (isOptional && val === void 0) + return; + if (!checkVal(val, object)) { + throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`); + } + }; + for (const [fieldName, type] of Object.entries(validators)) + checkField(fieldName, type, false); + for (const [fieldName, type] of Object.entries(optValidators)) + checkField(fieldName, type, true); + return object; + } + + // node_modules/@noble/curves/esm/abstract/modular.js + var _0n2 = BigInt(0); + var _1n2 = BigInt(1); + var _2n2 = BigInt(2); + var _3n = BigInt(3); + var _4n = BigInt(4); + var _5n = BigInt(5); + var _8n = BigInt(8); + var _9n = BigInt(9); + var _16n = BigInt(16); + function mod(a, b) { + const result = a % b; + return result >= _0n2 ? result : b + result; + } + function pow(num, power, modulo) { + if (modulo <= _0n2 || power < _0n2) + throw new Error("Expected power/modulo > 0"); + if (modulo === _1n2) + return _0n2; + let res = _1n2; + while (power > _0n2) { + if (power & _1n2) + res = res * num % modulo; + num = num * num % modulo; + power >>= _1n2; + } + return res; + } + function pow2(x, power, modulo) { + let res = x; + while (power-- > _0n2) { + res *= res; + res %= modulo; + } + return res; + } + function invert(number3, modulo) { + if (number3 === _0n2 || modulo <= _0n2) { + throw new Error(`invert: expected positive integers, got n=${number3} mod=${modulo}`); + } + let a = mod(number3, 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 tonelliShanks(P) { + const legendreC = (P - _1n2) / _2n2; + let Q, S, Z; + for (Q = P - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++) + ; + for (Z = _2n2; Z < P && pow(Z, legendreC, P) !== P - _1n2; Z++) + ; + if (S === 1) { + const p1div4 = (P + _1n2) / _4n; + return function tonelliFast(Fp2, n) { + const root = Fp2.pow(n, p1div4); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + const Q1div2 = (Q + _1n2) / _2n2; + return function tonelliSlow(Fp2, n) { + if (Fp2.pow(n, legendreC) === Fp2.neg(Fp2.ONE)) + throw new Error("Cannot find square root"); + let r = S; + let g = Fp2.pow(Fp2.mul(Fp2.ONE, Z), Q); + let x = Fp2.pow(n, Q1div2); + let b = Fp2.pow(n, Q); + while (!Fp2.eql(b, Fp2.ONE)) { + if (Fp2.eql(b, Fp2.ZERO)) + return Fp2.ZERO; + let m = 1; + for (let t2 = Fp2.sqr(b); m < r; m++) { + if (Fp2.eql(t2, Fp2.ONE)) + break; + t2 = Fp2.sqr(t2); + } + const ge2 = Fp2.pow(g, _1n2 << BigInt(r - m - 1)); + g = Fp2.sqr(ge2); + x = Fp2.mul(x, ge2); + b = Fp2.mul(b, g); + r = m; + } + return x; + }; + } + function FpSqrt(P) { + if (P % _4n === _3n) { + const p1div4 = (P + _1n2) / _4n; + return function sqrt3mod4(Fp2, n) { + const root = Fp2.pow(n, p1div4); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + if (P % _8n === _5n) { + const c1 = (P - _5n) / _8n; + return function sqrt5mod8(Fp2, n) { + const n2 = Fp2.mul(n, _2n2); + const v = Fp2.pow(n2, c1); + const nv = Fp2.mul(n, v); + const i2 = Fp2.mul(Fp2.mul(nv, _2n2), v); + const root = Fp2.mul(nv, Fp2.sub(i2, Fp2.ONE)); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + if (P % _16n === _9n) { + } + 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", + MASK: "bigint", + BYTES: "isSafeInteger", + BITS: "isSafeInteger" + }; + const opts = FIELD_FIELDS.reduce((map, val) => { + map[val] = "function"; + return map; + }, initial); + return validateObject(field, opts); + } + function FpPow(f, num, power) { + if (power < _0n2) + throw new Error("Expected power > 0"); + if (power === _0n2) + return f.ONE; + if (power === _1n2) + return num; + let p = f.ONE; + let d = num; + while (power > _0n2) { + if (power & _1n2) + p = f.mul(p, d); + d = f.sqr(d); + power >>= _1n2; + } + return p; + } + function FpInvertBatch(f, nums) { + const tmp = new Array(nums.length); + const lastMultiplied = nums.reduce((acc, num, i2) => { + if (f.is0(num)) + return acc; + tmp[i2] = acc; + return f.mul(acc, num); + }, f.ONE); + const inverted = f.inv(lastMultiplied); + nums.reduceRight((acc, num, i2) => { + if (f.is0(num)) + return acc; + tmp[i2] = f.mul(acc, tmp[i2]); + return f.mul(acc, num); + }, inverted); + return tmp; + } + function nLength(n, nBitLength) { + const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length; + const nByteLength = Math.ceil(_nBitLength / 8); + return { nBitLength: _nBitLength, nByteLength }; + } + function Field(ORDER, bitLen2, isLE3 = false, redef = {}) { + if (ORDER <= _0n2) + throw new Error(`Expected Field ORDER > 0, got ${ORDER}`); + const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2); + if (BYTES > 2048) + throw new Error("Field lengths over 2048 bytes are not supported"); + const sqrtP = FpSqrt(ORDER); + const f = Object.freeze({ + ORDER, + BITS, + BYTES, + MASK: bitMask(BITS), + ZERO: _0n2, + ONE: _1n2, + create: (num) => mod(num, ORDER), + isValid: (num) => { + if (typeof num !== "bigint") + throw new Error(`Invalid field element: expected bigint, got ${typeof num}`); + return _0n2 <= num && num < ORDER; + }, + is0: (num) => num === _0n2, + isOdd: (num) => (num & _1n2) === _1n2, + neg: (num) => mod(-num, ORDER), + eql: (lhs, rhs) => lhs === rhs, + sqr: (num) => mod(num * num, ORDER), + add: (lhs, rhs) => mod(lhs + rhs, ORDER), + sub: (lhs, rhs) => mod(lhs - rhs, ORDER), + mul: (lhs, rhs) => mod(lhs * rhs, ORDER), + pow: (num, power) => FpPow(f, num, power), + div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER), + sqrN: (num) => num * num, + addN: (lhs, rhs) => lhs + rhs, + subN: (lhs, rhs) => lhs - rhs, + mulN: (lhs, rhs) => lhs * rhs, + inv: (num) => invert(num, ORDER), + sqrt: redef.sqrt || ((n) => sqrtP(f, n)), + invertBatch: (lst) => FpInvertBatch(f, lst), + cmov: (a, b, c) => c ? b : a, + toBytes: (num) => isLE3 ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES), + fromBytes: (bytes3) => { + if (bytes3.length !== BYTES) + throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes3.length}`); + return isLE3 ? bytesToNumberLE(bytes3) : bytesToNumberBE(bytes3); + } + }); + return Object.freeze(f); + } + 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, isLE3 = false) { + 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 num = isLE3 ? bytesToNumberBE(key) : bytesToNumberLE(key); + const reduced = mod(num, fieldOrder - _1n2) + _1n2; + return isLE3 ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen); + } + + // node_modules/@noble/curves/esm/abstract/curve.js + var _0n3 = BigInt(0); + var _1n3 = BigInt(1); + function wNAF(c, bits) { + const constTimeNegate = (condition, item) => { + const neg = item.negate(); + return condition ? neg : item; + }; + const opts = (W) => { + const windows = Math.ceil(bits / W) + 1; + const windowSize = 2 ** (W - 1); + return { windows, windowSize }; + }; + return { + constTimeNegate, + unsafeLadder(elm, n) { + let p = c.ZERO; + let d = elm; + while (n > _0n3) { + if (n & _1n3) + p = p.add(d); + d = d.double(); + n >>= _1n3; + } + return p; + }, + precomputeWindow(elm, W) { + const { windows, windowSize } = opts(W); + const points = []; + let p = elm; + 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) { + const { windows, windowSize } = opts(W); + let p = c.ZERO; + let f = c.BASE; + const mask = BigInt(2 ** W - 1); + const maxNumber = 2 ** W; + const shiftBy = BigInt(W); + for (let window2 = 0; window2 < windows; window2++) { + const offset = window2 * windowSize; + let wbits = Number(n & mask); + n >>= shiftBy; + if (wbits > windowSize) { + wbits -= maxNumber; + n += _1n3; + } + const offset1 = offset; + const offset2 = offset + Math.abs(wbits) - 1; + const cond1 = window2 % 2 !== 0; + const cond2 = wbits < 0; + if (wbits === 0) { + f = f.add(constTimeNegate(cond1, precomputes[offset1])); + } else { + p = p.add(constTimeNegate(cond2, precomputes[offset2])); + } + } + return { p, f }; + }, + wNAFCached(P, precomputesMap, n, transform) { + const W = P._WINDOW_SIZE || 1; + let comp = precomputesMap.get(P); + if (!comp) { + comp = this.precomputeWindow(P, W); + if (W !== 1) { + precomputesMap.set(P, transform(comp)); + } + } + return this.wNAF(W, comp, n); + } + }; + } + function validateBasic(curve) { + validateField(curve.Fp); + validateObject(curve, { + n: "bigint", + h: "bigint", + Gx: "field", + Gy: "field" + }, { + nBitLength: "isSafeInteger", + nByteLength: "isSafeInteger" + }); + return Object.freeze({ + ...nLength(curve.n, curve.nBitLength), + ...curve, + ...{ p: curve.Fp.ORDER } + }); + } + + // node_modules/@noble/curves/esm/abstract/weierstrass.js + function validatePointOpts(curve) { + const opts = validateBasic(curve); + validateObject(opts, { + a: "field", + b: "field" + }, { + allowedPrivateKeyLengths: "array", + wrapPrivateKey: "boolean", + isTorsionFree: "function", + clearCofactor: "function", + allowInfinityPoint: "boolean", + fromBytes: "function", + toBytes: "function" + }); + const { endo, Fp: Fp2, a } = opts; + if (endo) { + if (!Fp2.eql(a, Fp2.ZERO)) { + throw new Error("Endomorphism can only be defined for Koblitz curves that have a=0"); + } + if (typeof endo !== "object" || typeof endo.beta !== "bigint" || typeof endo.splitScalar !== "function") { + throw new Error("Expected endomorphism with beta: bigint and splitScalar: function"); + } + } + return Object.freeze({ ...opts }); + } + var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports; + var DER = { + Err: class DERErr extends Error { + constructor(m = "") { + super(m); + } + }, + _parseInt(data) { + const { Err: E } = DER; + if (data.length < 2 || data[0] !== 2) + throw new E("Invalid signature integer tag"); + const len = data[1]; + const res = data.subarray(2, len + 2); + if (!len || res.length !== len) + throw new E("Invalid signature integer: wrong length"); + if (res[0] & 128) + throw new E("Invalid signature integer: negative"); + if (res[0] === 0 && !(res[1] & 128)) + throw new E("Invalid signature integer: unnecessary leading zero"); + return { d: b2n(res), l: data.subarray(len + 2) }; + }, + toSig(hex2) { + const { Err: E } = DER; + const data = typeof hex2 === "string" ? h2b(hex2) : hex2; + if (!(data instanceof Uint8Array)) + throw new Error("ui8a expected"); + let l = data.length; + if (l < 2 || data[0] != 48) + throw new E("Invalid signature tag"); + if (data[1] !== l - 2) + throw new E("Invalid signature: incorrect length"); + const { d: r, l: sBytes } = DER._parseInt(data.subarray(2)); + const { d: s, l: rBytesLeft } = DER._parseInt(sBytes); + if (rBytesLeft.length) + throw new E("Invalid signature: left bytes after parsing"); + return { r, s }; + }, + hexFromSig(sig) { + const slice = (s2) => Number.parseInt(s2[0], 16) & 8 ? "00" + s2 : s2; + const h = (num) => { + const hex2 = num.toString(16); + return hex2.length & 1 ? `0${hex2}` : hex2; + }; + const s = slice(h(sig.s)); + const r = slice(h(sig.r)); + const shl = s.length / 2; + const rhl = r.length / 2; + const sl = h(shl); + const rl = h(rhl); + return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`; + } + }; + var _0n4 = BigInt(0); + var _1n4 = BigInt(1); + var _2n3 = BigInt(2); + var _3n2 = BigInt(3); + var _4n2 = BigInt(4); + function weierstrassPoints(opts) { + const CURVE = validatePointOpts(opts); + const { Fp: Fp2 } = CURVE; + const toBytes3 = CURVE.toBytes || ((_c, point, _isCompressed) => { + const a = point.toAffine(); + return concatBytes2(Uint8Array.from([4]), Fp2.toBytes(a.x), Fp2.toBytes(a.y)); + }); + const fromBytes = CURVE.fromBytes || ((bytes3) => { + const tail = bytes3.subarray(1); + const x = Fp2.fromBytes(tail.subarray(0, Fp2.BYTES)); + const y = Fp2.fromBytes(tail.subarray(Fp2.BYTES, 2 * Fp2.BYTES)); + return { x, y }; + }); + function weierstrassEquation(x) { + const { a, b } = CURVE; + const x2 = Fp2.sqr(x); + const x3 = Fp2.mul(x2, x); + return Fp2.add(Fp2.add(x3, Fp2.mul(x, a)), b); + } + if (!Fp2.eql(Fp2.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx))) + throw new Error("bad generator point: equation left != right"); + function isWithinCurveOrder(num) { + return typeof num === "bigint" && _0n4 < num && num < CURVE.n; + } + function assertGE(num) { + if (!isWithinCurveOrder(num)) + throw new Error("Expected valid bigint: 0 < bigint < curve.n"); + } + function normPrivateKeyToScalar(key) { + const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE; + if (lengths && typeof key !== "bigint") { + if (key instanceof Uint8Array) + key = bytesToHex(key); + if (typeof key !== "string" || !lengths.includes(key.length)) + throw new Error("Invalid key"); + key = key.padStart(nByteLength * 2, "0"); + } + let num; + try { + num = typeof key === "bigint" ? key : bytesToNumberBE(ensureBytes("private key", key, nByteLength)); + } catch (error) { + throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`); + } + if (wrapPrivateKey) + num = mod(num, n); + assertGE(num); + return num; + } + const pointPrecomputes = /* @__PURE__ */ new Map(); + function assertPrjPoint(other) { + if (!(other instanceof Point2)) + throw new Error("ProjectivePoint expected"); + } + class Point2 { + constructor(px, py, pz) { + this.px = px; + this.py = py; + this.pz = pz; + if (px == null || !Fp2.isValid(px)) + throw new Error("x required"); + if (py == null || !Fp2.isValid(py)) + throw new Error("y required"); + if (pz == null || !Fp2.isValid(pz)) + throw new Error("z required"); + } + static fromAffine(p) { + const { x, y } = p || {}; + if (!p || !Fp2.isValid(x) || !Fp2.isValid(y)) + throw new Error("invalid affine point"); + if (p instanceof Point2) + throw new Error("projective point not allowed"); + const is0 = (i2) => Fp2.eql(i2, Fp2.ZERO); + if (is0(x) && is0(y)) + return Point2.ZERO; + return new Point2(x, y, Fp2.ONE); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + static normalizeZ(points) { + const toInv = Fp2.invertBatch(points.map((p) => p.pz)); + return points.map((p, i2) => p.toAffine(toInv[i2])).map(Point2.fromAffine); + } + static fromHex(hex2) { + const P = Point2.fromAffine(fromBytes(ensureBytes("pointHex", hex2))); + P.assertValidity(); + return P; + } + static fromPrivateKey(privateKey) { + return Point2.BASE.multiply(normPrivateKeyToScalar(privateKey)); + } + _setWindowSize(windowSize) { + this._WINDOW_SIZE = windowSize; + pointPrecomputes.delete(this); + } + assertValidity() { + if (this.is0()) { + if (CURVE.allowInfinityPoint && !Fp2.is0(this.py)) + return; + throw new Error("bad point: ZERO"); + } + const { x, y } = this.toAffine(); + if (!Fp2.isValid(x) || !Fp2.isValid(y)) + throw new Error("bad point: x or y not FE"); + const left = Fp2.sqr(y); + const right = weierstrassEquation(x); + if (!Fp2.eql(left, right)) + throw new Error("bad point: equation left != right"); + if (!this.isTorsionFree()) + throw new Error("bad point: not in prime-order subgroup"); + } + hasEvenY() { + const { y } = this.toAffine(); + if (Fp2.isOdd) + return !Fp2.isOdd(y); + throw new Error("Field doesn't support isOdd"); + } + equals(other) { + assertPrjPoint(other); + const { px: X1, py: Y1, pz: Z1 } = this; + const { px: X2, py: Y2, pz: Z2 } = other; + const U1 = Fp2.eql(Fp2.mul(X1, Z2), Fp2.mul(X2, Z1)); + const U2 = Fp2.eql(Fp2.mul(Y1, Z2), Fp2.mul(Y2, Z1)); + return U1 && U2; + } + negate() { + return new Point2(this.px, Fp2.neg(this.py), this.pz); + } + double() { + const { a, b } = CURVE; + const b3 = Fp2.mul(b, _3n2); + const { px: X1, py: Y1, pz: Z1 } = this; + let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO; + let t0 = Fp2.mul(X1, X1); + let t1 = Fp2.mul(Y1, Y1); + let t2 = Fp2.mul(Z1, Z1); + let t3 = Fp2.mul(X1, Y1); + t3 = Fp2.add(t3, t3); + Z3 = Fp2.mul(X1, Z1); + Z3 = Fp2.add(Z3, Z3); + X3 = Fp2.mul(a, Z3); + Y3 = Fp2.mul(b3, t2); + Y3 = Fp2.add(X3, Y3); + X3 = Fp2.sub(t1, Y3); + Y3 = Fp2.add(t1, Y3); + Y3 = Fp2.mul(X3, Y3); + X3 = Fp2.mul(t3, X3); + Z3 = Fp2.mul(b3, Z3); + t2 = Fp2.mul(a, t2); + t3 = Fp2.sub(t0, t2); + t3 = Fp2.mul(a, t3); + t3 = Fp2.add(t3, Z3); + Z3 = Fp2.add(t0, t0); + t0 = Fp2.add(Z3, t0); + t0 = Fp2.add(t0, t2); + t0 = Fp2.mul(t0, t3); + Y3 = Fp2.add(Y3, t0); + t2 = Fp2.mul(Y1, Z1); + t2 = Fp2.add(t2, t2); + t0 = Fp2.mul(t2, t3); + X3 = Fp2.sub(X3, t0); + Z3 = Fp2.mul(t2, t1); + Z3 = Fp2.add(Z3, Z3); + Z3 = Fp2.add(Z3, Z3); + return new Point2(X3, Y3, Z3); + } + add(other) { + assertPrjPoint(other); + const { px: X1, py: Y1, pz: Z1 } = this; + const { px: X2, py: Y2, pz: Z2 } = other; + let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO; + const a = CURVE.a; + const b3 = Fp2.mul(CURVE.b, _3n2); + let t0 = Fp2.mul(X1, X2); + let t1 = Fp2.mul(Y1, Y2); + let t2 = Fp2.mul(Z1, Z2); + let t3 = Fp2.add(X1, Y1); + let t4 = Fp2.add(X2, Y2); + t3 = Fp2.mul(t3, t4); + t4 = Fp2.add(t0, t1); + t3 = Fp2.sub(t3, t4); + t4 = Fp2.add(X1, Z1); + let t5 = Fp2.add(X2, Z2); + t4 = Fp2.mul(t4, t5); + t5 = Fp2.add(t0, t2); + t4 = Fp2.sub(t4, t5); + t5 = Fp2.add(Y1, Z1); + X3 = Fp2.add(Y2, Z2); + t5 = Fp2.mul(t5, X3); + X3 = Fp2.add(t1, t2); + t5 = Fp2.sub(t5, X3); + Z3 = Fp2.mul(a, t4); + X3 = Fp2.mul(b3, t2); + Z3 = Fp2.add(X3, Z3); + X3 = Fp2.sub(t1, Z3); + Z3 = Fp2.add(t1, Z3); + Y3 = Fp2.mul(X3, Z3); + t1 = Fp2.add(t0, t0); + t1 = Fp2.add(t1, t0); + t2 = Fp2.mul(a, t2); + t4 = Fp2.mul(b3, t4); + t1 = Fp2.add(t1, t2); + t2 = Fp2.sub(t0, t2); + t2 = Fp2.mul(a, t2); + t4 = Fp2.add(t4, t2); + t0 = Fp2.mul(t1, t4); + Y3 = Fp2.add(Y3, t0); + t0 = Fp2.mul(t5, t4); + X3 = Fp2.mul(t3, X3); + X3 = Fp2.sub(X3, t0); + t0 = Fp2.mul(t3, t1); + Z3 = Fp2.mul(t5, Z3); + Z3 = Fp2.add(Z3, t0); + return new Point2(X3, Y3, Z3); + } + subtract(other) { + return this.add(other.negate()); + } + is0() { + return this.equals(Point2.ZERO); + } + wNAF(n) { + return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => { + const toInv = Fp2.invertBatch(comp.map((p) => p.pz)); + return comp.map((p, i2) => p.toAffine(toInv[i2])).map(Point2.fromAffine); + }); + } + multiplyUnsafe(n) { + const I = Point2.ZERO; + if (n === _0n4) + return I; + assertGE(n); + if (n === _1n4) + return this; + const { endo } = CURVE; + if (!endo) + return wnaf.unsafeLadder(this, n); + let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n); + let k1p = I; + let k2p = I; + let d = this; + while (k1 > _0n4 || k2 > _0n4) { + if (k1 & _1n4) + k1p = k1p.add(d); + if (k2 & _1n4) + k2p = k2p.add(d); + d = d.double(); + k1 >>= _1n4; + k2 >>= _1n4; + } + if (k1neg) + k1p = k1p.negate(); + if (k2neg) + k2p = k2p.negate(); + k2p = new Point2(Fp2.mul(k2p.px, endo.beta), k2p.py, k2p.pz); + return k1p.add(k2p); + } + multiply(scalar) { + assertGE(scalar); + let n = scalar; + let point, fake; + const { endo } = CURVE; + if (endo) { + const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n); + let { p: k1p, f: f1p } = this.wNAF(k1); + let { p: k2p, f: f2p } = this.wNAF(k2); + k1p = wnaf.constTimeNegate(k1neg, k1p); + k2p = wnaf.constTimeNegate(k2neg, k2p); + k2p = new Point2(Fp2.mul(k2p.px, endo.beta), k2p.py, k2p.pz); + point = k1p.add(k2p); + fake = f1p.add(f2p); + } else { + const { p, f } = this.wNAF(n); + point = p; + fake = f; + } + return Point2.normalizeZ([point, fake])[0]; + } + multiplyAndAddUnsafe(Q, a, b) { + const G = Point2.BASE; + const mul = (P, a2) => a2 === _0n4 || a2 === _1n4 || !P.equals(G) ? P.multiplyUnsafe(a2) : P.multiply(a2); + const sum = mul(this, a).add(mul(Q, b)); + return sum.is0() ? void 0 : sum; + } + toAffine(iz) { + const { px: x, py: y, pz: z } = this; + const is0 = this.is0(); + if (iz == null) + iz = is0 ? Fp2.ONE : Fp2.inv(z); + const ax = Fp2.mul(x, iz); + const ay = Fp2.mul(y, iz); + const zz = Fp2.mul(z, iz); + if (is0) + return { x: Fp2.ZERO, y: Fp2.ZERO }; + if (!Fp2.eql(zz, Fp2.ONE)) + throw new Error("invZ was invalid"); + return { x: ax, y: ay }; + } + isTorsionFree() { + const { h: cofactor, isTorsionFree } = CURVE; + if (cofactor === _1n4) + return true; + if (isTorsionFree) + return isTorsionFree(Point2, this); + throw new Error("isTorsionFree() has not been declared for the elliptic curve"); + } + clearCofactor() { + const { h: cofactor, clearCofactor } = CURVE; + if (cofactor === _1n4) + return this; + if (clearCofactor) + return clearCofactor(Point2, this); + return this.multiplyUnsafe(CURVE.h); + } + toRawBytes(isCompressed = true) { + this.assertValidity(); + return toBytes3(Point2, this, isCompressed); + } + toHex(isCompressed = true) { + return bytesToHex(this.toRawBytes(isCompressed)); + } + } + Point2.BASE = new Point2(CURVE.Gx, CURVE.Gy, Fp2.ONE); + Point2.ZERO = new Point2(Fp2.ZERO, Fp2.ONE, Fp2.ZERO); + const _bits = CURVE.nBitLength; + const wnaf = wNAF(Point2, CURVE.endo ? Math.ceil(_bits / 2) : _bits); + return { + CURVE, + ProjectivePoint: Point2, + normPrivateKeyToScalar, + weierstrassEquation, + isWithinCurveOrder + }; + } + function validateOpts(curve) { + const opts = validateBasic(curve); + validateObject(opts, { + hash: "hash", + hmac: "function", + randomBytes: "function" + }, { + bits2int: "function", + bits2int_modN: "function", + lowS: "boolean" + }); + return Object.freeze({ lowS: true, ...opts }); + } + function weierstrass(curveDef) { + const CURVE = validateOpts(curveDef); + const { Fp: Fp2, n: CURVE_ORDER } = CURVE; + const compressedLen = Fp2.BYTES + 1; + const uncompressedLen = 2 * Fp2.BYTES + 1; + function isValidFieldElement(num) { + return _0n4 < num && num < Fp2.ORDER; + } + function modN2(a) { + return mod(a, CURVE_ORDER); + } + function invN(a) { + return invert(a, CURVE_ORDER); + } + const { ProjectivePoint: Point2, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder } = weierstrassPoints({ + ...CURVE, + toBytes(_c, point, isCompressed) { + const a = point.toAffine(); + const x = Fp2.toBytes(a.x); + const cat = concatBytes2; + if (isCompressed) { + return cat(Uint8Array.from([point.hasEvenY() ? 2 : 3]), x); + } else { + return cat(Uint8Array.from([4]), x, Fp2.toBytes(a.y)); + } + }, + fromBytes(bytes3) { + const len = bytes3.length; + const head = bytes3[0]; + const tail = bytes3.subarray(1); + if (len === compressedLen && (head === 2 || head === 3)) { + const x = bytesToNumberBE(tail); + if (!isValidFieldElement(x)) + throw new Error("Point is not on curve"); + const y2 = weierstrassEquation(x); + let y = Fp2.sqrt(y2); + const isYOdd = (y & _1n4) === _1n4; + const isHeadOdd = (head & 1) === 1; + if (isHeadOdd !== isYOdd) + y = Fp2.neg(y); + return { x, y }; + } else if (len === uncompressedLen && head === 4) { + const x = Fp2.fromBytes(tail.subarray(0, Fp2.BYTES)); + const y = Fp2.fromBytes(tail.subarray(Fp2.BYTES, 2 * Fp2.BYTES)); + return { x, y }; + } else { + throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`); + } + } + }); + const numToNByteStr = (num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength)); + function isBiggerThanHalfOrder(number3) { + const HALF = CURVE_ORDER >> _1n4; + return number3 > HALF; + } + function normalizeS(s) { + return isBiggerThanHalfOrder(s) ? modN2(-s) : s; + } + const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to)); + class Signature { + constructor(r, s, recovery) { + this.r = r; + this.s = s; + this.recovery = recovery; + this.assertValidity(); + } + static fromCompact(hex2) { + const l = CURVE.nByteLength; + hex2 = ensureBytes("compactSignature", hex2, l * 2); + return new Signature(slcNum(hex2, 0, l), slcNum(hex2, l, 2 * l)); + } + static fromDER(hex2) { + const { r, s } = DER.toSig(ensureBytes("DER", hex2)); + return new Signature(r, s); + } + assertValidity() { + if (!isWithinCurveOrder(this.r)) + throw new Error("r must be 0 < r < CURVE.n"); + if (!isWithinCurveOrder(this.s)) + throw new Error("s must be 0 < s < CURVE.n"); + } + addRecoveryBit(recovery) { + return new Signature(this.r, this.s, recovery); + } + recoverPublicKey(msgHash) { + const { r, s, recovery: rec } = this; + const h = bits2int_modN(ensureBytes("msgHash", msgHash)); + if (rec == null || ![0, 1, 2, 3].includes(rec)) + throw new Error("recovery id invalid"); + const radj = rec === 2 || rec === 3 ? r + CURVE.n : r; + if (radj >= Fp2.ORDER) + throw new Error("recovery id 2 or 3 invalid"); + const prefix = (rec & 1) === 0 ? "02" : "03"; + const R = Point2.fromHex(prefix + numToNByteStr(radj)); + const ir = invN(radj); + const u1 = modN2(-h * ir); + const u2 = modN2(s * ir); + const Q = Point2.BASE.multiplyAndAddUnsafe(R, u1, u2); + if (!Q) + throw new Error("point at infinify"); + Q.assertValidity(); + return Q; + } + hasHighS() { + return isBiggerThanHalfOrder(this.s); + } + normalizeS() { + return this.hasHighS() ? new Signature(this.r, modN2(-this.s), this.recovery) : this; + } + toDERRawBytes() { + return hexToBytes(this.toDERHex()); + } + toDERHex() { + return DER.hexFromSig({ r: this.r, s: this.s }); + } + toCompactRawBytes() { + return hexToBytes(this.toCompactHex()); + } + toCompactHex() { + return numToNByteStr(this.r) + numToNByteStr(this.s); + } + } + const utils = { + isValidPrivateKey(privateKey) { + try { + normPrivateKeyToScalar(privateKey); + return true; + } catch (error) { + return false; + } + }, + normPrivateKeyToScalar, + randomPrivateKey: () => { + const length = getMinHashLength(CURVE.n); + return mapHashToField(CURVE.randomBytes(length), CURVE.n); + }, + precompute(windowSize = 8, point = Point2.BASE) { + point._setWindowSize(windowSize); + point.multiply(BigInt(3)); + return point; + } + }; + function getPublicKey2(privateKey, isCompressed = true) { + return Point2.fromPrivateKey(privateKey).toRawBytes(isCompressed); + } + function isProbPub(item) { + const arr = item instanceof Uint8Array; + const str = typeof item === "string"; + const len = (arr || str) && item.length; + if (arr) + return len === compressedLen || len === uncompressedLen; + if (str) + return len === 2 * compressedLen || len === 2 * uncompressedLen; + if (item instanceof Point2) + return true; + return false; + } + function getSharedSecret(privateA, publicB, isCompressed = true) { + if (isProbPub(privateA)) + throw new Error("first arg must be private key"); + if (!isProbPub(publicB)) + throw new Error("second arg must be public key"); + const b = Point2.fromHex(publicB); + return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed); + } + const bits2int = CURVE.bits2int || function(bytes3) { + const num = bytesToNumberBE(bytes3); + const delta = bytes3.length * 8 - CURVE.nBitLength; + return delta > 0 ? num >> BigInt(delta) : num; + }; + const bits2int_modN = CURVE.bits2int_modN || function(bytes3) { + return modN2(bits2int(bytes3)); + }; + const ORDER_MASK = bitMask(CURVE.nBitLength); + function int2octets(num) { + if (typeof num !== "bigint") + throw new Error("bigint expected"); + if (!(_0n4 <= num && num < ORDER_MASK)) + throw new Error(`bigint expected < 2^${CURVE.nBitLength}`); + return numberToBytesBE(num, CURVE.nByteLength); + } + function prepSig(msgHash, privateKey, opts = defaultSigOpts) { + if (["recovered", "canonical"].some((k) => k in opts)) + throw new Error("sign() legacy options not supported"); + const { hash: hash3, randomBytes: randomBytes2 } = CURVE; + let { lowS, prehash, extraEntropy: ent } = opts; + if (lowS == null) + lowS = true; + msgHash = ensureBytes("msgHash", msgHash); + if (prehash) + msgHash = ensureBytes("prehashed msgHash", hash3(msgHash)); + const h1int = bits2int_modN(msgHash); + const d = normPrivateKeyToScalar(privateKey); + const seedArgs = [int2octets(d), int2octets(h1int)]; + if (ent != null) { + const e = ent === true ? randomBytes2(Fp2.BYTES) : ent; + seedArgs.push(ensureBytes("extraEntropy", e)); + } + const seed = concatBytes2(...seedArgs); + const m = h1int; + function k2sig(kBytes) { + const k = bits2int(kBytes); + if (!isWithinCurveOrder(k)) + return; + const ik = invN(k); + const q = Point2.BASE.multiply(k).toAffine(); + const r = modN2(q.x); + if (r === _0n4) + return; + const s = modN2(ik * modN2(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 = normalizeS(s); + recovery ^= 1; + } + return new Signature(r, normS, recovery); + } + return { seed, k2sig }; + } + const defaultSigOpts = { lowS: CURVE.lowS, prehash: false }; + const defaultVerOpts = { lowS: CURVE.lowS, prehash: false }; + function sign(msgHash, privKey, opts = defaultSigOpts) { + const { seed, k2sig } = prepSig(msgHash, privKey, opts); + const C = CURVE; + const drbg = createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac); + return drbg(seed, k2sig); + } + Point2.BASE._setWindowSize(8); + function verify(signature, msgHash, publicKey, opts = defaultVerOpts) { + const sg = signature; + msgHash = ensureBytes("msgHash", msgHash); + publicKey = ensureBytes("publicKey", publicKey); + if ("strict" in opts) + throw new Error("options.strict was renamed to lowS"); + const { lowS, prehash } = opts; + let _sig = void 0; + let P; + try { + if (typeof sg === "string" || sg instanceof Uint8Array) { + try { + _sig = Signature.fromDER(sg); + } catch (derError) { + if (!(derError instanceof DER.Err)) + throw derError; + _sig = Signature.fromCompact(sg); + } + } else if (typeof sg === "object" && typeof sg.r === "bigint" && typeof sg.s === "bigint") { + const { r: r2, s: s2 } = sg; + _sig = new Signature(r2, s2); + } else { + throw new Error("PARSE"); + } + P = Point2.fromHex(publicKey); + } catch (error) { + if (error.message === "PARSE") + throw new Error(`signature must be Signature instance, Uint8Array or hex string`); + return false; + } + if (lowS && _sig.hasHighS()) + return false; + if (prehash) + msgHash = CURVE.hash(msgHash); + const { r, s } = _sig; + const h = bits2int_modN(msgHash); + const is = invN(s); + const u1 = modN2(h * is); + const u2 = modN2(r * is); + const R = Point2.BASE.multiplyAndAddUnsafe(P, u1, u2)?.toAffine(); + if (!R) + return false; + const v = modN2(R.x); + return v === r; + } + return { + CURVE, + getPublicKey: getPublicKey2, + getSharedSecret, + sign, + verify, + ProjectivePoint: Point2, + Signature, + utils + }; + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/hmac.js + var HMAC = class extends Hash { + constructor(hash3, _key) { + super(); + this.finished = false; + this.destroyed = false; + hash(hash3); + const key = toBytes(_key); + this.iHash = hash3.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 pad = new Uint8Array(blockLen); + pad.set(key.length > blockLen ? hash3.create().update(key).digest() : key); + for (let i2 = 0; i2 < pad.length; i2++) + pad[i2] ^= 54; + this.iHash.update(pad); + this.oHash = hash3.create(); + for (let i2 = 0; i2 < pad.length; i2++) + pad[i2] ^= 54 ^ 92; + this.oHash.update(pad); + pad.fill(0); + } + update(buf) { + exists(this); + this.iHash.update(buf); + return this; + } + digestInto(out) { + exists(this); + bytes(out, this.outputLen); + 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 || (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; + } + destroy() { + this.destroyed = true; + this.oHash.destroy(); + this.iHash.destroy(); + } + }; + var hmac = (hash3, key, message) => new HMAC(hash3, key).update(message).digest(); + hmac.create = (hash3, key) => new HMAC(hash3, key); + + // node_modules/@noble/curves/esm/_shortw_utils.js + function getHash(hash3) { + return { + hash: hash3, + hmac: (key, ...msgs) => hmac(hash3, key, concatBytes(...msgs)), + randomBytes + }; + } + function createCurve(curveDef, defHash) { + const create = (hash3) => weierstrass({ ...curveDef, ...getHash(hash3) }); + return Object.freeze({ ...create(defHash), create }); + } + + // node_modules/@noble/curves/esm/secp256k1.js + var secp256k1P = BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"); + var secp256k1N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"); + var _1n5 = BigInt(1); + var _2n4 = BigInt(2); + var divNearest = (a, b) => (a + b / _2n4) / b; + function sqrtMod(y) { + const P = secp256k1P; + 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, _2n4, 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, _2n4, P); + if (!Fp.eql(Fp.sqr(root), y)) + throw new Error("Cannot find square root"); + return root; + } + var Fp = Field(secp256k1P, void 0, void 0, { sqrt: sqrtMod }); + var secp256k1 = createCurve({ + a: BigInt(0), + b: BigInt(7), + Fp, + n: secp256k1N, + Gx: BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"), + Gy: BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"), + h: BigInt(1), + lowS: true, + endo: { + beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"), + splitScalar: (k) => { + const n = secp256k1N; + const a1 = BigInt("0x3086d221a7d46bcde86c90e49284eb15"); + const b1 = -_1n5 * BigInt("0xe4437ed6010e88286f547fa90abfe4c3"); + const a2 = BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"); + const b2 = a1; + const POW_2_128 = BigInt("0x100000000000000000000000000000000"); + const c1 = divNearest(b2 * k, n); + const c2 = divNearest(-b1 * k, n); + let k1 = mod(k - c1 * a1 - c2 * a2, n); + let k2 = mod(-c1 * b1 - c2 * b2, n); + const k1neg = k1 > POW_2_128; + const k2neg = k2 > POW_2_128; + if (k1neg) + k1 = n - k1; + if (k2neg) + k2 = n - k2; + if (k1 > POW_2_128 || k2 > POW_2_128) { + throw new Error("splitScalar: Endomorphism failed, k=" + k); + } + return { k1neg, k1, k2neg, k2 }; + } + } + }, sha256); + var _0n5 = BigInt(0); + var fe = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1P; + var ge = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1N; + var TAGGED_HASH_PREFIXES = {}; + function taggedHash(tag, ...messages) { + let tagP = TAGGED_HASH_PREFIXES[tag]; + if (tagP === void 0) { + const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0))); + tagP = concatBytes2(tagH, tagH); + TAGGED_HASH_PREFIXES[tag] = tagP; + } + return sha256(concatBytes2(tagP, ...messages)); + } + var pointToBytes = (point) => point.toRawBytes(true).slice(1); + var numTo32b = (n) => numberToBytesBE(n, 32); + var modP = (x) => mod(x, secp256k1P); + var modN = (x) => mod(x, secp256k1N); + var Point = secp256k1.ProjectivePoint; + var GmulAdd = (Q, a, b) => Point.BASE.multiplyAndAddUnsafe(Q, a, b); + function schnorrGetExtPubKey(priv) { + let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); + let p = Point.fromPrivateKey(d_); + const scalar = p.hasEvenY() ? d_ : modN(-d_); + return { scalar, bytes: pointToBytes(p) }; + } + function lift_x(x) { + if (!fe(x)) + throw new Error("bad x: need 0 < x < p"); + const xx = modP(x * x); + const c = modP(xx * x + BigInt(7)); + let y = sqrtMod(c); + if (y % _2n4 !== _0n5) + y = modP(-y); + const p = new Point(x, y, _1n5); + p.assertValidity(); + return p; + } + function challenge(...args) { + return modN(bytesToNumberBE(taggedHash("BIP0340/challenge", ...args))); + } + function schnorrGetPublicKey(privateKey) { + return schnorrGetExtPubKey(privateKey).bytes; + } + function schnorrSign(message, privateKey, auxRand = randomBytes(32)) { + const m = ensureBytes("message", message); + const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey); + const a = ensureBytes("auxRand", auxRand, 32); + const t = numTo32b(d ^ bytesToNumberBE(taggedHash("BIP0340/aux", a))); + const rand = taggedHash("BIP0340/nonce", t, px, m); + const k_ = modN(bytesToNumberBE(rand)); + if (k_ === _0n5) + throw new Error("sign failed: k is zero"); + const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); + const e = challenge(rx, px, m); + const sig = new Uint8Array(64); + sig.set(rx, 0); + sig.set(numTo32b(modN(k + e * d)), 32); + if (!schnorrVerify(sig, m, px)) + throw new Error("sign: Invalid signature produced"); + return sig; + } + function schnorrVerify(signature, message, publicKey) { + const sig = ensureBytes("signature", signature, 64); + const m = ensureBytes("message", message); + const pub = ensureBytes("publicKey", publicKey, 32); + try { + const P = lift_x(bytesToNumberBE(pub)); + const r = bytesToNumberBE(sig.subarray(0, 32)); + if (!fe(r)) + return false; + const s = bytesToNumberBE(sig.subarray(32, 64)); + if (!ge(s)) + return false; + const e = challenge(numTo32b(r), pointToBytes(P), m); + const R = GmulAdd(P, s, modN(-e)); + if (!R || !R.hasEvenY() || R.toAffine().x !== r) + return false; + return true; + } catch (error) { + return false; + } + } + var schnorr = /* @__PURE__ */ (() => ({ + getPublicKey: schnorrGetPublicKey, + sign: schnorrSign, + verify: schnorrVerify, + utils: { + randomPrivateKey: secp256k1.utils.randomPrivateKey, + lift_x, + pointToBytes, + numberToBytesBE, + bytesToNumberBE, + taggedHash, + mod + } + }))(); + + // node_modules/@noble/hashes/esm/crypto.js + var crypto2 = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0; + + // node_modules/@noble/hashes/esm/utils.js + var u8a3 = (a) => a instanceof Uint8Array; + var createView2 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); + var rotr2 = (word, shift) => word << 32 - shift | word >>> shift; + var isLE2 = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68; + if (!isLE2) + throw new Error("Non little-endian hardware is not supported"); + var hexes2 = Array.from({ length: 256 }, (v, i2) => i2.toString(16).padStart(2, "0")); + function bytesToHex2(bytes3) { + if (!u8a3(bytes3)) + throw new Error("Uint8Array expected"); + let hex2 = ""; + for (let i2 = 0; i2 < bytes3.length; i2++) { + hex2 += hexes2[bytes3[i2]]; + } + return hex2; + } + function hexToBytes2(hex2) { + if (typeof hex2 !== "string") + throw new Error("hex string expected, got " + typeof hex2); + const len = hex2.length; + if (len % 2) + throw new Error("padded hex string expected, got unpadded hex of length " + len); + const array = new Uint8Array(len / 2); + for (let i2 = 0; i2 < array.length; i2++) { + const j = i2 * 2; + const hexByte = hex2.slice(j, j + 2); + const byte = Number.parseInt(hexByte, 16); + if (Number.isNaN(byte) || byte < 0) + throw new Error("Invalid byte sequence"); + array[i2] = byte; + } + return array; + } + function utf8ToBytes3(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function toBytes2(data) { + if (typeof data === "string") + data = utf8ToBytes3(data); + if (!u8a3(data)) + throw new Error(`expected Uint8Array, got ${typeof data}`); + return data; + } + var Hash2 = class { + clone() { + return this._cloneInto(); + } + }; + function wrapConstructor2(hashCons) { + const hashC = (msg) => hashCons().update(toBytes2(msg)).digest(); + const tmp = hashCons(); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = () => hashCons(); + return hashC; + } + + // node_modules/@noble/hashes/esm/_assert.js + function number2(n) { + if (!Number.isSafeInteger(n) || n < 0) + throw new Error(`Wrong positive integer: ${n}`); + } + function bool(b) { + if (typeof b !== "boolean") + throw new Error(`Expected boolean, not ${b}`); + } + function bytes2(b, ...lengths) { + if (!(b instanceof Uint8Array)) + throw new Error("Expected Uint8Array"); + if (lengths.length > 0 && !lengths.includes(b.length)) + throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`); + } + function hash2(hash3) { + if (typeof hash3 !== "function" || typeof hash3.create !== "function") + throw new Error("Hash should be wrapped by utils.wrapConstructor"); + number2(hash3.outputLen); + number2(hash3.blockLen); + } + function exists2(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 output2(out, instance) { + bytes2(out); + const min = instance.outputLen; + if (out.length < min) { + throw new Error(`digestInto() expects output buffer of length at least ${min}`); + } + } + var assert = { + number: number2, + bool, + bytes: bytes2, + hash: hash2, + exists: exists2, + output: output2 + }; + var assert_default = assert; + + // node_modules/@noble/hashes/esm/_sha2.js + function setBigUint642(view, byteOffset, value, isLE3) { + if (typeof view.setBigUint64 === "function") + return view.setBigUint64(byteOffset, value, isLE3); + const _32n = BigInt(32); + const _u32_max = BigInt(4294967295); + const wh = Number(value >> _32n & _u32_max); + const wl = Number(value & _u32_max); + const h = isLE3 ? 4 : 0; + const l = isLE3 ? 0 : 4; + view.setUint32(byteOffset + h, wh, isLE3); + view.setUint32(byteOffset + l, wl, isLE3); + } + var SHA22 = class extends Hash2 { + constructor(blockLen, outputLen, padOffset, isLE3) { + super(); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE3; + this.finished = false; + this.length = 0; + this.pos = 0; + this.destroyed = false; + this.buffer = new Uint8Array(blockLen); + this.view = createView2(this.buffer); + } + update(data) { + assert_default.exists(this); + const { view, buffer, blockLen } = this; + data = toBytes2(data); + const len = data.length; + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + if (take === blockLen) { + const dataView = createView2(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) { + assert_default.exists(this); + assert_default.output(out, this); + this.finished = true; + const { buffer, view, blockLen, isLE: isLE3 } = this; + let { pos } = this; + buffer[pos++] = 128; + this.buffer.subarray(pos).fill(0); + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + for (let i2 = pos; i2 < blockLen; i2++) + buffer[i2] = 0; + setBigUint642(view, blockLen - 8, BigInt(this.length * 8), isLE3); + this.process(view, 0); + const oview = createView2(out); + const len = this.outputLen; + if (len % 4) + throw new Error("_sha2: outputLen should 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], isLE3); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to || (to = new this.constructor()); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.length = length; + to.pos = pos; + to.finished = finished; + to.destroyed = destroyed; + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + }; + + // node_modules/@noble/hashes/esm/sha256.js + var Chi2 = (a, b, c) => a & b ^ ~a & c; + var Maj2 = (a, b, c) => a & b ^ a & c ^ b & c; + var SHA256_K2 = new Uint32Array([ + 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 IV2 = new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 + ]); + var SHA256_W2 = new Uint32Array(64); + var SHA2562 = class extends SHA22 { + constructor() { + super(64, 32, 8, false); + this.A = IV2[0] | 0; + this.B = IV2[1] | 0; + this.C = IV2[2] | 0; + this.D = IV2[3] | 0; + this.E = IV2[4] | 0; + this.F = IV2[5] | 0; + this.G = IV2[6] | 0; + this.H = IV2[7] | 0; + } + 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_W2[i2] = view.getUint32(offset, false); + for (let i2 = 16; i2 < 64; i2++) { + const W15 = SHA256_W2[i2 - 15]; + const W2 = SHA256_W2[i2 - 2]; + const s0 = rotr2(W15, 7) ^ rotr2(W15, 18) ^ W15 >>> 3; + const s1 = rotr2(W2, 17) ^ rotr2(W2, 19) ^ W2 >>> 10; + SHA256_W2[i2] = s1 + SHA256_W2[i2 - 7] + s0 + SHA256_W2[i2 - 16] | 0; + } + let { A, B, C, D, E, F, G, H } = this; + for (let i2 = 0; i2 < 64; i2++) { + const sigma1 = rotr2(E, 6) ^ rotr2(E, 11) ^ rotr2(E, 25); + const T1 = H + sigma1 + Chi2(E, F, G) + SHA256_K2[i2] + SHA256_W2[i2] | 0; + const sigma0 = rotr2(A, 2) ^ rotr2(A, 13) ^ rotr2(A, 22); + const T2 = sigma0 + Maj2(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() { + SHA256_W2.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0); + this.buffer.fill(0); + } + }; + var SHA224 = class extends SHA2562 { + constructor() { + super(); + this.A = 3238371032 | 0; + this.B = 914150663 | 0; + this.C = 812702999 | 0; + this.D = 4144912697 | 0; + this.E = 4290775857 | 0; + this.F = 1750603025 | 0; + this.G = 1694076839 | 0; + this.H = 3204075428 | 0; + this.outputLen = 28; + } + }; + var sha2562 = wrapConstructor2(() => new SHA2562()); + var sha224 = wrapConstructor2(() => new SHA224()); + + // node_modules/nostr-tools/lib/esm/pool.js + 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] === "object") + return false; + } + } + return true; + } + var utf8Decoder = new TextDecoder("utf-8"); + var utf8Encoder = new TextEncoder(); + function normalizeURL(url) { + if (url.indexOf("://") === -1) + url = "wss://" + url; + let p = new URL(url); + 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(); + } + var QueueNode = class { + value; + next = null; + prev = null; + constructor(message) { + this.value = message; + } + }; + var Queue = class { + first; + last; + constructor() { + this.first = null; + this.last = null; + } + enqueue(value) { + const newNode = new QueueNode(value); + if (!this.last) { + this.first = newNode; + this.last = newNode; + } else if (this.last === this.first) { + this.last = newNode; + this.last.prev = this.first; + this.first.next = newNode; + } else { + newNode.prev = this.last; + this.last.next = newNode; + this.last = newNode; + } + return true; + } + dequeue() { + if (!this.first) + return null; + if (this.first === this.last) { + const target2 = this.first; + this.first = null; + this.last = null; + return target2.value; + } + const target = this.first; + this.first = target.next; + return target.value; + } + }; + var JS = class { + generateSecretKey() { + return schnorr.utils.randomPrivateKey(); + } + getPublicKey(secretKey) { + return bytesToHex2(schnorr.getPublicKey(secretKey)); + } + finalizeEvent(t, secretKey) { + const event = t; + event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey)); + event.id = getEventHash(event); + event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey)); + event[verifiedSymbol] = true; + return event; + } + verifyEvent(event) { + if (typeof event[verifiedSymbol] === "boolean") + return event[verifiedSymbol]; + const hash3 = getEventHash(event); + if (hash3 !== event.id) { + event[verifiedSymbol] = false; + return false; + } + try { + const valid = schnorr.verify(event.sig, hash3, 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 = sha2562(utf8Encoder.encode(serializeEvent(event))); + return bytesToHex2(eventHash); + } + var i = new JS(); + var generateSecretKey = i.generateSecretKey; + var getPublicKey = i.getPublicKey; + var finalizeEvent = i.finalizeEvent; + var verifyEvent = i.verifyEvent; + var ClientAuth = 22242; + 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 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 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 makeAuthEvent(relayURL, challenge2) { + return { + kind: ClientAuth, + created_at: Math.floor(Date.now() / 1e3), + tags: [ + ["relay", relayURL], + ["challenge", challenge2] + ], + content: "" + }; + } + async function yieldThread() { + return new Promise((resolve) => { + const ch = new MessageChannel(); + const handler = () => { + ch.port1.removeEventListener("message", handler); + resolve(); + }; + ch.port1.addEventListener("message", handler); + ch.port2.postMessage(0); + ch.port1.start(); + }); + } + var alwaysTrue = (t) => { + t[verifiedSymbol] = true; + return true; + }; + var AbstractRelay = class { + url; + _connected = false; + onclose = null; + onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`); + _onauth = null; + baseEoseTimeout = 4400; + connectionTimeout = 4400; + openSubs = /* @__PURE__ */ new Map(); + connectionTimeoutHandle; + connectionPromise; + openCountRequests = /* @__PURE__ */ new Map(); + openEventPublishes = /* @__PURE__ */ new Map(); + ws; + incomingMessageQueue = new Queue(); + queueRunning = false; + challenge; + serial = 0; + verifyEvent; + _WebSocket; + constructor(url, opts) { + this.url = normalizeURL(url); + this.verifyEvent = opts.verifyEvent; + this._WebSocket = opts.websocketImplementation || WebSocket; + } + static async connect(url, opts) { + const relay = new AbstractRelay(url, opts); + await relay.connect(); + 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 connect() { + if (this.connectionPromise) + return this.connectionPromise; + this.challenge = void 0; + this.connectionPromise = new Promise((resolve, reject) => { + this.connectionTimeoutHandle = setTimeout(() => { + reject("connection timed out"); + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection timed out"); + }, this.connectionTimeout); + try { + this.ws = new this._WebSocket(this.url); + } catch (err) { + reject(err); + return; + } + this.ws.onopen = () => { + clearTimeout(this.connectionTimeoutHandle); + this._connected = true; + resolve(); + }; + this.ws.onerror = (ev) => { + reject(ev.message || "websocket error"); + if (this._connected) { + this._connected = false; + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection errored"); + } + }; + this.ws.onclose = async () => { + if (this._connected) { + this._connected = false; + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection closed"); + } + }; + this.ws.onmessage = this._onmessage.bind(this); + }); + return this.connectionPromise; + } + async runQueue() { + this.queueRunning = true; + while (true) { + if (false === this.handleNext()) { + break; + } + await yieldThread(); + } + this.queueRunning = false; + } + handleNext() { + const json = this.incomingMessageQueue.dequeue(); + if (!json) { + return false; + } + 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); + } + 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 (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]; + this._onauth?.(data[1]); + return; + } + } + } catch (err) { + return; + } + } + async send(message) { + if (!this.connectionPromise) + throw new Error("sending on closed connection"); + this.connectionPromise.then(() => { + this.ws?.send(message); + }); + } + async auth(signAuthEvent) { + if (!this.challenge) + throw new Error("can't perform auth, no challenge was received"); + const evt = await signAuthEvent(makeAuthEvent(this.url, this.challenge)); + const ret = new Promise((resolve, reject) => { + this.openEventPublishes.set(evt.id, { resolve, reject }); + }); + this.send('["AUTH",' + JSON.stringify(evt) + "]"); + return ret; + } + async publish(event) { + const ret = new Promise((resolve, reject) => { + this.openEventPublishes.set(event.id, { resolve, reject }); + }); + this.send('["EVENT",' + JSON.stringify(event) + "]"); + 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) { + const subscription = this.prepareSubscription(filters, params); + subscription.fire(); + return subscription; + } + prepareSubscription(filters, params) { + this.serial++; + const id = params.id || "sub:" + this.serial; + const subscription = new Subscription(this, id, filters, params); + this.openSubs.set(id, subscription); + return subscription; + } + close() { + this.closeAllSubscriptions("relay connection closed by us"); + this._connected = false; + this.ws?.close(); + } + _onmessage(ev) { + this.incomingMessageQueue.enqueue(ev.data); + if (!this.queueRunning) { + this.runQueue(); + } + } + }; + var Subscription = class { + relay; + id; + closed = false; + eosed = false; + filters; + alreadyHaveEvent; + receivedEvent; + onevent; + oneose; + onclose; + eoseTimeout; + eoseTimeoutHandle; + constructor(relay, id, filters, params) { + 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) { + this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]"); + this.closed = true; + } + this.relay.openSubs.delete(this.id); + this.onclose?.(reason); + } + }; + var AbstractSimplePool = class { + relays = /* @__PURE__ */ new Map(); + seenOn = /* @__PURE__ */ new Map(); + trackRelays = false; + verifyEvent; + trustedRelayURLs = /* @__PURE__ */ new Set(); + _WebSocket; + constructor(opts) { + this.verifyEvent = opts.verifyEvent; + this._WebSocket = opts.websocketImplementation; + } + 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 + }); + if (params?.connectionTimeout) + relay.connectionTimeout = params.connectionTimeout; + this.relays.set(url, relay); + } + await relay.connect(); + return relay; + } + close(relays) { + relays.map(normalizeURL).forEach((url) => { + this.relays.get(url)?.close(); + }); + } + subscribeMany(relays, filters, params) { + return this.subscribeManyMap(Object.fromEntries(relays.map((url) => [url, filters])), params); + } + subscribeManyMap(requests, params) { + 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 relaysLength = Object.keys(requests).length; + const eosesReceived = []; + let handleEose = (i2) => { + eosesReceived[i2] = true; + if (eosesReceived.filter((a) => a).length === relaysLength) { + params.oneose?.(); + handleEose = () => { + }; + } + }; + const closesReceived = []; + let handleClose = (i2, reason) => { + handleEose(i2); + closesReceived[i2] = reason; + if (closesReceived.filter((a) => a).length === relaysLength) { + 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( + Object.entries(requests).map(async (req, i2, arr) => { + if (arr.indexOf(req) !== i2) { + handleClose(i2, "duplicate url"); + return; + } + let [url, filters] = req; + url = normalizeURL(url); + let relay; + try { + relay = await this.ensureRelay(url, { + connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : void 0 + }); + } catch (err) { + handleClose(i2, err?.message || String(err)); + return; + } + let subscription = relay.subscribe(filters, { + ...params, + oneose: () => handleEose(i2), + onclose: (reason) => handleClose(i2, reason), + alreadyHaveEvent: localAlreadyHaveEventHandler, + eoseTimeout: params.maxWait + }); + subs.push(subscription); + }) + ); + return { + async close() { + await allOpened; + subs.forEach((sub) => { + sub.close(); + }); + } + }; + } + subscribeManyEose(relays, filters, params) { + const subcloser = this.subscribeMany(relays, filters, { + ...params, + oneose() { + subcloser.close(); + } + }); + return subcloser; + } + async querySync(relays, filter, params) { + return new Promise(async (resolve) => { + const events = []; + this.subscribeManyEose(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) { + return relays.map(normalizeURL).map(async (url, i2, arr) => { + if (arr.indexOf(url) !== i2) { + return Promise.reject("duplicate url"); + } + let r = await this.ensureRelay(url); + return r.publish(event); + }); + } + }; + var _WebSocket; + try { + _WebSocket = WebSocket; + } catch { + } + var SimplePool = class extends AbstractSimplePool { + constructor() { + super({ verifyEvent, websocketImplementation: _WebSocket }); + } + }; + + // node_modules/@scure/base/lib/esm/index.js + function assertNumber(n) { + if (!Number.isSafeInteger(n)) + throw new Error(`Wrong integer: ${n}`); + } + function chain(...args) { + const wrap = (a, b) => (c) => a(b(c)); + const encode = Array.from(args).reverse().reduce((acc, i2) => acc ? wrap(acc, i2.encode) : i2.encode, void 0); + const decode2 = args.reduce((acc, i2) => acc ? wrap(acc, i2.decode) : i2.decode, void 0); + return { encode, decode: decode2 }; + } + function alphabet(alphabet2) { + return { + encode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("alphabet.encode input should be an array of numbers"); + return digits.map((i2) => { + assertNumber(i2); + if (i2 < 0 || i2 >= alphabet2.length) + throw new Error(`Digit index outside alphabet: ${i2} (alphabet: ${alphabet2.length})`); + return alphabet2[i2]; + }); + }, + decode: (input) => { + if (!Array.isArray(input) || input.length && typeof input[0] !== "string") + throw new Error("alphabet.decode input should be array of strings"); + return input.map((letter) => { + if (typeof letter !== "string") + throw new Error(`alphabet.decode: not string element=${letter}`); + const index = alphabet2.indexOf(letter); + if (index === -1) + throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet2}`); + return index; + }); + } + }; + } + function join(separator = "") { + if (typeof separator !== "string") + throw new Error("join separator should be string"); + return { + encode: (from) => { + if (!Array.isArray(from) || from.length && typeof from[0] !== "string") + throw new Error("join.encode input should be array of strings"); + for (let i2 of from) + if (typeof i2 !== "string") + throw new Error(`join.encode: non-string input=${i2}`); + return from.join(separator); + }, + decode: (to) => { + if (typeof to !== "string") + throw new Error("join.decode input should be string"); + return to.split(separator); + } + }; + } + function padding(bits, chr = "=") { + assertNumber(bits); + if (typeof chr !== "string") + throw new Error("padding chr should be string"); + return { + encode(data) { + if (!Array.isArray(data) || data.length && typeof data[0] !== "string") + throw new Error("padding.encode input should be array of strings"); + for (let i2 of data) + if (typeof i2 !== "string") + throw new Error(`padding.encode: non-string input=${i2}`); + while (data.length * bits % 8) + data.push(chr); + return data; + }, + decode(input) { + if (!Array.isArray(input) || input.length && typeof input[0] !== "string") + throw new Error("padding.encode input should be array of strings"); + for (let i2 of input) + if (typeof i2 !== "string") + throw new Error(`padding.decode: non-string input=${i2}`); + let end = input.length; + if (end * bits % 8) + throw new Error("Invalid padding: string should have whole number of bytes"); + for (; end > 0 && input[end - 1] === chr; end--) { + if (!((end - 1) * bits % 8)) + throw new Error("Invalid padding: string has too much padding"); + } + return input.slice(0, end); + } + }; + } + function normalize(fn) { + if (typeof fn !== "function") + throw new Error("normalize fn should be function"); + return { encode: (from) => from, decode: (to) => fn(to) }; + } + function convertRadix(data, from, to) { + if (from < 2) + throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`); + if (to < 2) + throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`); + if (!Array.isArray(data)) + throw new Error("convertRadix: data should be array"); + if (!data.length) + return []; + let pos = 0; + const res = []; + const digits = Array.from(data); + digits.forEach((d) => { + assertNumber(d); + if (d < 0 || d >= from) + throw new Error(`Wrong integer: ${d}`); + }); + while (true) { + let carry = 0; + let done = true; + for (let i2 = pos; i2 < digits.length; i2++) { + const digit = digits[i2]; + const digitBase = from * carry + digit; + if (!Number.isSafeInteger(digitBase) || from * carry / from !== carry || digitBase - digit !== from * carry) { + throw new Error("convertRadix: carry overflow"); + } + carry = digitBase % to; + digits[i2] = Math.floor(digitBase / to); + if (!Number.isSafeInteger(digits[i2]) || digits[i2] * to + carry !== digitBase) + throw new Error("convertRadix: carry overflow"); + if (!done) + continue; + else if (!digits[i2]) + 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 ? a : gcd(b, a % b); + var radix2carry = (from, to) => from + (to - gcd(from, to)); + function convertRadix2(data, from, to, padding2) { + if (!Array.isArray(data)) + throw new Error("convertRadix2: data should be array"); + 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 mask = 2 ** to - 1; + const res = []; + for (const n of data) { + assertNumber(n); + if (n >= 2 ** from) + 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); + carry &= 2 ** pos - 1; + } + carry = carry << to - pos & mask; + if (!padding2 && pos >= from) + throw new Error("Excess padding"); + if (!padding2 && carry) + throw new Error(`Non-zero padding: ${carry}`); + if (padding2 && pos > 0) + res.push(carry >>> 0); + return res; + } + function radix(num) { + assertNumber(num); + return { + encode: (bytes3) => { + if (!(bytes3 instanceof Uint8Array)) + throw new Error("radix.encode input should be Uint8Array"); + return convertRadix(Array.from(bytes3), 2 ** 8, num); + }, + decode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("radix.decode input should be array of strings"); + return Uint8Array.from(convertRadix(digits, num, 2 ** 8)); + } + }; + } + function radix2(bits, revPadding = false) { + assertNumber(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: (bytes3) => { + if (!(bytes3 instanceof Uint8Array)) + throw new Error("radix2.encode input should be Uint8Array"); + return convertRadix2(Array.from(bytes3), 8, bits, !revPadding); + }, + decode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("radix2.decode input should be array of strings"); + return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding)); + } + }; + } + function unsafeWrapper(fn) { + if (typeof fn !== "function") + throw new Error("unsafeWrapper fn should be function"); + 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 base32hex = chain(radix2(5), alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUV"), padding(5), join("")); + var base32crockford = chain(radix2(5), alphabet("0123456789ABCDEFGHJKMNPQRSTVWXYZ"), join(""), normalize((s) => s.toUpperCase().replace(/O/g, "0").replace(/[IL]/g, "1"))); + var base64 = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), padding(6), join("")); + var base64url = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), padding(6), join("")); + var genBase58 = (abc) => chain(radix(58), alphabet(abc), join("")); + var base58 = genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); + var base58flickr = genBase58("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); + var base58xrp = genBase58("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"); + var XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11]; + var base58xmr = { + encode(data) { + let res = ""; + for (let i2 = 0; i2 < data.length; i2 += 8) { + const block = data.subarray(i2, i2 + 8); + res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], "1"); + } + return res; + }, + decode(str) { + let res = []; + for (let i2 = 0; i2 < str.length; i2 += 11) { + const slice = str.slice(i2, i2 + 11); + const blockLen = XMR_BLOCK_LEN.indexOf(slice.length); + const block = base58.decode(slice); + for (let j = 0; j < block.length - blockLen; j++) { + if (block[j] !== 0) + throw new Error("base58xmr: wrong padding"); + } + res = res.concat(Array.from(block.slice(block.length - blockLen))); + } + return Uint8Array.from(res); + } + }; + 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 % 2 ** 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) { + if (typeof prefix !== "string") + throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`); + if (!Array.isArray(words) || words.length && typeof words[0] !== "number") + throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`); + const actualLength = prefix.length + 7 + words.length; + if (limit !== false && actualLength > limit) + throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`); + prefix = prefix.toLowerCase(); + return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`; + } + function decode2(str, limit = 90) { + if (typeof str !== "string") + throw new Error(`bech32.decode input should be string, not ${typeof str}`); + if (str.length < 8 || limit !== false && str.length > limit) + throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`); + const lowered = str.toLowerCase(); + if (str !== lowered && str !== str.toUpperCase()) + throw new Error(`String must be lowercase or uppercase`); + str = lowered; + const sepIndex = str.lastIndexOf("1"); + if (sepIndex === 0 || sepIndex === -1) + throw new Error(`Letter "1" must be present between prefix and data only`); + const prefix = str.slice(0, sepIndex); + const _words2 = str.slice(sepIndex + 1); + if (_words2.length < 6) + throw new Error("Data must be at least 6 characters long"); + const words = BECH_ALPHABET.decode(_words2).slice(0, -6); + const sum = bechChecksum(prefix, words, ENCODING_CONST); + if (!_words2.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) }; + } + return { encode, decode: decode2, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords }; + } + var bech32 = genBech32("bech32"); + var bech32m = genBech32("bech32m"); + var utf8 = { + encode: (data) => new TextDecoder().decode(data), + decode: (str) => new TextEncoder().encode(str) + }; + var hex = chain(radix2(4), alphabet("0123456789abcdef"), join(""), normalize((s) => { + if (typeof s !== "string" || s.length % 2) + throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`); + return s.toLowerCase(); + })); + var CODERS = { + utf8, + hex, + base16, + base32, + base64, + base64url, + base58, + base58xmr + }; + var coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(", ")}`; + + // node_modules/nostr-tools/lib/esm/nip19.js + var utf8Decoder2 = new TextDecoder("utf-8"); + var utf8Encoder2 = new TextEncoder(); + var Bech32MaxSize = 5e3; + function decode(nip19) { + let { prefix, words } = bech32.decode(nip19, 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: bytesToHex2(tlv[0][0]), + relays: tlv[1] ? tlv[1].map((d) => utf8Decoder2.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: bytesToHex2(tlv[0][0]), + relays: tlv[1] ? tlv[1].map((d) => utf8Decoder2.decode(d)) : [], + author: tlv[2]?.[0] ? bytesToHex2(tlv[2][0]) : void 0, + kind: tlv[3]?.[0] ? parseInt(bytesToHex2(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: utf8Decoder2.decode(tlv[0][0]), + pubkey: bytesToHex2(tlv[2][0]), + kind: parseInt(bytesToHex2(tlv[3][0]), 16), + relays: tlv[1] ? tlv[1].map((d) => utf8Decoder2.decode(d)) : [] + } + }; + } + case "nrelay": { + let tlv = parseTLV(data); + if (!tlv[0]?.[0]) + throw new Error("missing TLV 0 for nrelay"); + return { + type: "nrelay", + data: utf8Decoder2.decode(tlv[0][0]) + }; + } + case "nsec": + return { type: prefix, data }; + case "npub": + case "note": + return { type: prefix, data: bytesToHex2(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 npubEncode(hex2) { + return encodeBytes("npub", hexToBytes2(hex2)); + } + function encodeBech32(prefix, data) { + let words = bech32.toWords(data); + return bech32.encode(prefix, words, Bech32MaxSize); + } + function encodeBytes(prefix, bytes3) { + return encodeBech32(prefix, bytes3); + } + + // node_modules/nostr-tools/lib/esm/nip05.js + var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/; + var _fetch; + try { + _fetch = fetch; + } catch { + } + 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 (await _fetch(url, { redirect: "error" })).json(); + let pubkey = res.names[name]; + return pubkey ? { pubkey, relays: res.relays?.[pubkey] } : null; + } catch (_e) { + return null; + } + } + + // metadata.ts + var import_lru_cache = __toESM(require_lru_cache(), 1); + var pool = window.nostrSharedPool || new SimplePool(); + var metadataCache = window.nostrMetadataCache || new import_lru_cache.default(2e3); + function fetchMetadata(pubkey, hints) { + let metadata = metadataCache.get(pubkey); + if (metadata) + return metadata; + const relays = ["wss://purplepag.es", "wss://user.kindpag.es", "wss://relay.nos.social"]; + relays.push(...hints); + let promise = new Promise( + (resolve, reject) => pool.subscribeManyEose( + relays, + [ + { + kinds: [0], + authors: [pubkey] + } + ], + { + onevent(evt) { + try { + resolve(JSON.parse(evt.content)); + } catch (err) { + } + }, + onclose: reject + } + ) + ); + metadataCache.set(pubkey, promise); + return promise; + } + async function inputToPubkey(input) { + try { + const { type, data } = decode(input); + if (type === "nprofile") { + return [data.pubkey, data.relays || []]; + } else if (type === "npub") { + return [data, []]; + } + } catch (err) { + if (input.match(/[0-9a-f]{64}/)) { + return [input, []]; + } else if (input.match(".")) { + let res = await queryProfile(input); + if (!res) + return [void 0]; + return [res.pubkey, res.relays || []]; + } + } + return [void 0]; + } + function getShortName(pubkey, metadata) { + let name = metadata.name || metadata.display_name; + if (name) + return name; + let npub = npubEncode(pubkey); + return shortenNpub(npub); + } + function shortenNpub(npub) { + return npub.substring(0, 7) + "\u2026" + npub.substring(57); + } + + // nostr-name.ts + var import_debounce = __toESM(require_debounce(), 1); + var NostrName = class extends HTMLElement { + constructor() { + super(); + this.set(); + } + connectedCallback() { + this.set(); + } + attributeChangedCallback() { + this.set(); + } + set = (0, import_debounce.default)(async () => { + let input = this.getAttribute("pubkey"); + if (input) { + let [pubkey, hints] = await inputToPubkey(input); + if (pubkey) { + let metadata = await fetchMetadata(pubkey, hints || []); + this.textContent = getShortName(pubkey, metadata); + } + } + }, 200); + }; + __publicField(NostrName, "observedAttributes", ["pubkey"]); + window.customElements.define("nostr-name", NostrName); +})(); diff --git a/public/lib/nostr-picture.js b/public/lib/nostr-picture.js new file mode 100644 index 0000000..3590e41 --- /dev/null +++ b/public/lib/nostr-picture.js @@ -0,0 +1,4050 @@ +"use strict"; +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __commonJS = (cb, mod2) => function __require() { + return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; + }; + 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 __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( + isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, + mod2 + )); + var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; + }; + + // node_modules/obliterator/iterator.js + var require_iterator = __commonJS({ + "node_modules/obliterator/iterator.js"(exports, module) { + function Iterator(next) { + if (typeof next !== "function") + throw new Error("obliterator/iterator: expecting a function!"); + this.next = next; + } + if (typeof Symbol !== "undefined") + Iterator.prototype[Symbol.iterator] = function() { + return this; + }; + Iterator.of = function() { + var args = arguments, l = args.length, i2 = 0; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + return { done: false, value: args[i2++] }; + }); + }; + Iterator.empty = function() { + var iterator = new Iterator(function() { + return { done: true }; + }); + return iterator; + }; + Iterator.fromSequence = function(sequence) { + var i2 = 0, l = sequence.length; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + return { done: false, value: sequence[i2++] }; + }); + }; + Iterator.is = function(value) { + if (value instanceof Iterator) + return true; + return typeof value === "object" && value !== null && typeof value.next === "function"; + }; + module.exports = Iterator; + } + }); + + // node_modules/obliterator/support.js + var require_support = __commonJS({ + "node_modules/obliterator/support.js"(exports) { + exports.ARRAY_BUFFER_SUPPORT = typeof ArrayBuffer !== "undefined"; + exports.SYMBOL_SUPPORT = typeof Symbol !== "undefined"; + } + }); + + // node_modules/obliterator/foreach.js + var require_foreach = __commonJS({ + "node_modules/obliterator/foreach.js"(exports, module) { + var support = require_support(); + var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; + var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; + module.exports = function forEach(iterable, callback) { + var iterator, k, i2, l, s; + if (!iterable) + throw new Error("obliterator/forEach: invalid iterable."); + if (typeof callback !== "function") + throw new Error("obliterator/forEach: expecting a callback."); + if (Array.isArray(iterable) || ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(iterable) || typeof iterable === "string" || iterable.toString() === "[object Arguments]") { + for (i2 = 0, l = iterable.length; i2 < l; i2++) + callback(iterable[i2], i2); + return; + } + if (typeof iterable.forEach === "function") { + iterable.forEach(callback); + return; + } + if (SYMBOL_SUPPORT && Symbol.iterator in iterable && typeof iterable.next !== "function") { + iterable = iterable[Symbol.iterator](); + } + if (typeof iterable.next === "function") { + iterator = iterable; + i2 = 0; + while (s = iterator.next(), s.done !== true) { + callback(s.value, i2); + i2++; + } + return; + } + for (k in iterable) { + if (iterable.hasOwnProperty(k)) { + callback(iterable[k], k); + } + } + return; + }; + } + }); + + // node_modules/mnemonist/utils/typed-arrays.js + var require_typed_arrays = __commonJS({ + "node_modules/mnemonist/utils/typed-arrays.js"(exports) { + var MAX_8BIT_INTEGER = Math.pow(2, 8) - 1; + var MAX_16BIT_INTEGER = Math.pow(2, 16) - 1; + var MAX_32BIT_INTEGER = Math.pow(2, 32) - 1; + var MAX_SIGNED_8BIT_INTEGER = Math.pow(2, 7) - 1; + var MAX_SIGNED_16BIT_INTEGER = Math.pow(2, 15) - 1; + var MAX_SIGNED_32BIT_INTEGER = Math.pow(2, 31) - 1; + exports.getPointerArray = function(size) { + var maxIndex = size - 1; + if (maxIndex <= MAX_8BIT_INTEGER) + return Uint8Array; + if (maxIndex <= MAX_16BIT_INTEGER) + return Uint16Array; + if (maxIndex <= MAX_32BIT_INTEGER) + return Uint32Array; + throw new Error("mnemonist: Pointer Array of size > 4294967295 is not supported."); + }; + exports.getSignedPointerArray = function(size) { + var maxIndex = size - 1; + if (maxIndex <= MAX_SIGNED_8BIT_INTEGER) + return Int8Array; + if (maxIndex <= MAX_SIGNED_16BIT_INTEGER) + return Int16Array; + if (maxIndex <= MAX_SIGNED_32BIT_INTEGER) + return Int32Array; + return Float64Array; + }; + exports.getNumberType = function(value) { + if (value === (value | 0)) { + if (Math.sign(value) === -1) { + if (value <= 127 && value >= -128) + return Int8Array; + if (value <= 32767 && value >= -32768) + return Int16Array; + return Int32Array; + } else { + if (value <= 255) + return Uint8Array; + if (value <= 65535) + return Uint16Array; + return Uint32Array; + } + } + return Float64Array; + }; + var TYPE_PRIORITY = { + Uint8Array: 1, + Int8Array: 2, + Uint16Array: 3, + Int16Array: 4, + Uint32Array: 5, + Int32Array: 6, + Float32Array: 7, + Float64Array: 8 + }; + exports.getMinimalRepresentation = function(array, getter) { + var maxType = null, maxPriority = 0, p, t, v, i2, l; + for (i2 = 0, l = array.length; i2 < l; i2++) { + v = getter ? getter(array[i2]) : array[i2]; + t = exports.getNumberType(v); + p = TYPE_PRIORITY[t.name]; + if (p > maxPriority) { + maxPriority = p; + maxType = t; + } + } + return maxType; + }; + exports.isTypedArray = function(value) { + return typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(value); + }; + exports.concat = function() { + var length = 0, i2, o, l; + for (i2 = 0, l = arguments.length; i2 < l; i2++) + length += arguments[i2].length; + var array = new arguments[0].constructor(length); + for (i2 = 0, o = 0; i2 < l; i2++) { + array.set(arguments[i2], o); + o += arguments[i2].length; + } + return array; + }; + exports.indices = function(length) { + var PointerArray = exports.getPointerArray(length); + var array = new PointerArray(length); + for (var i2 = 0; i2 < length; i2++) + array[i2] = i2; + return array; + }; + } + }); + + // node_modules/mnemonist/utils/iterables.js + var require_iterables = __commonJS({ + "node_modules/mnemonist/utils/iterables.js"(exports) { + var forEach = require_foreach(); + var typed = require_typed_arrays(); + function isArrayLike(target) { + return Array.isArray(target) || typed.isTypedArray(target); + } + function guessLength(target) { + if (typeof target.length === "number") + return target.length; + if (typeof target.size === "number") + return target.size; + return; + } + function toArray(target) { + var l = guessLength(target); + var array = typeof l === "number" ? new Array(l) : []; + var i2 = 0; + forEach(target, function(value) { + array[i2++] = value; + }); + return array; + } + function toArrayWithIndices(target) { + var l = guessLength(target); + var IndexArray = typeof l === "number" ? typed.getPointerArray(l) : Array; + var array = typeof l === "number" ? new Array(l) : []; + var indices = typeof l === "number" ? new IndexArray(l) : []; + var i2 = 0; + forEach(target, function(value) { + array[i2] = value; + indices[i2] = i2++; + }); + return [array, indices]; + } + exports.isArrayLike = isArrayLike; + exports.guessLength = guessLength; + exports.toArray = toArray; + exports.toArrayWithIndices = toArrayWithIndices; + } + }); + + // node_modules/mnemonist/lru-cache.js + var require_lru_cache = __commonJS({ + "node_modules/mnemonist/lru-cache.js"(exports, module) { + var Iterator = require_iterator(); + var forEach = require_foreach(); + var typed = require_typed_arrays(); + var iterables = require_iterables(); + function LRUCache2(Keys, Values, capacity) { + if (arguments.length < 2) { + capacity = Keys; + Keys = null; + Values = null; + } + this.capacity = capacity; + if (typeof this.capacity !== "number" || this.capacity <= 0) + throw new Error("mnemonist/lru-cache: capacity should be positive number."); + else if (!isFinite(this.capacity) || Math.floor(this.capacity) !== this.capacity) + throw new Error("mnemonist/lru-cache: capacity should be a finite positive integer."); + var PointerArray = typed.getPointerArray(capacity); + this.forward = new PointerArray(capacity); + this.backward = new PointerArray(capacity); + this.K = typeof Keys === "function" ? new Keys(capacity) : new Array(capacity); + this.V = typeof Values === "function" ? new Values(capacity) : new Array(capacity); + this.size = 0; + this.head = 0; + this.tail = 0; + this.items = {}; + } + LRUCache2.prototype.clear = function() { + this.size = 0; + this.head = 0; + this.tail = 0; + this.items = {}; + }; + LRUCache2.prototype.splayOnTop = function(pointer) { + var oldHead = this.head; + if (this.head === pointer) + return this; + var previous = this.backward[pointer], next = this.forward[pointer]; + if (this.tail === pointer) { + this.tail = previous; + } else { + this.backward[next] = previous; + } + this.forward[previous] = next; + this.backward[oldHead] = pointer; + this.head = pointer; + this.forward[pointer] = oldHead; + return this; + }; + LRUCache2.prototype.set = function(key, value) { + var pointer = this.items[key]; + if (typeof pointer !== "undefined") { + this.splayOnTop(pointer); + this.V[pointer] = value; + return; + } + if (this.size < this.capacity) { + pointer = this.size++; + } else { + pointer = this.tail; + this.tail = this.backward[pointer]; + delete this.items[this.K[pointer]]; + } + this.items[key] = pointer; + this.K[pointer] = key; + this.V[pointer] = value; + this.forward[pointer] = this.head; + this.backward[this.head] = pointer; + this.head = pointer; + }; + LRUCache2.prototype.setpop = function(key, value) { + var oldValue = null; + var oldKey = null; + var pointer = this.items[key]; + if (typeof pointer !== "undefined") { + this.splayOnTop(pointer); + oldValue = this.V[pointer]; + this.V[pointer] = value; + return { evicted: false, key, value: oldValue }; + } + if (this.size < this.capacity) { + pointer = this.size++; + } else { + pointer = this.tail; + this.tail = this.backward[pointer]; + oldValue = this.V[pointer]; + oldKey = this.K[pointer]; + delete this.items[oldKey]; + } + this.items[key] = pointer; + this.K[pointer] = key; + this.V[pointer] = value; + this.forward[pointer] = this.head; + this.backward[this.head] = pointer; + this.head = pointer; + if (oldKey) { + return { evicted: true, key: oldKey, value: oldValue }; + } else { + return null; + } + }; + LRUCache2.prototype.has = function(key) { + return key in this.items; + }; + LRUCache2.prototype.get = function(key) { + var pointer = this.items[key]; + if (typeof pointer === "undefined") + return; + this.splayOnTop(pointer); + return this.V[pointer]; + }; + LRUCache2.prototype.peek = function(key) { + var pointer = this.items[key]; + if (typeof pointer === "undefined") + return; + return this.V[pointer]; + }; + LRUCache2.prototype.forEach = function(callback, scope) { + scope = arguments.length > 1 ? scope : this; + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, values = this.V, forward = this.forward; + while (i2 < l) { + callback.call(scope, values[pointer], keys[pointer], this); + pointer = forward[pointer]; + i2++; + } + }; + LRUCache2.prototype.keys = function() { + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var key = keys[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value: key + }; + }); + }; + LRUCache2.prototype.values = function() { + var i2 = 0, l = this.size; + var pointer = this.head, values = this.V, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var value = values[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value + }; + }); + }; + LRUCache2.prototype.entries = function() { + var i2 = 0, l = this.size; + var pointer = this.head, keys = this.K, values = this.V, forward = this.forward; + return new Iterator(function() { + if (i2 >= l) + return { done: true }; + var key = keys[pointer], value = values[pointer]; + i2++; + if (i2 < l) + pointer = forward[pointer]; + return { + done: false, + value: [key, value] + }; + }); + }; + if (typeof Symbol !== "undefined") + LRUCache2.prototype[Symbol.iterator] = LRUCache2.prototype.entries; + LRUCache2.prototype.inspect = function() { + var proxy = /* @__PURE__ */ new Map(); + var iterator = this.entries(), step; + while (step = iterator.next(), !step.done) + proxy.set(step.value[0], step.value[1]); + Object.defineProperty(proxy, "constructor", { + value: LRUCache2, + enumerable: false + }); + return proxy; + }; + if (typeof Symbol !== "undefined") + LRUCache2.prototype[Symbol.for("nodejs.util.inspect.custom")] = LRUCache2.prototype.inspect; + LRUCache2.from = function(iterable, Keys, Values, capacity) { + if (arguments.length < 2) { + capacity = iterables.guessLength(iterable); + if (typeof capacity !== "number") + throw new Error("mnemonist/lru-cache.from: could not guess iterable length. Please provide desired capacity as last argument."); + } else if (arguments.length === 2) { + capacity = Keys; + Keys = null; + Values = null; + } + var cache = new LRUCache2(Keys, Values, capacity); + forEach(iterable, function(value, key) { + cache.set(key, value); + }); + return cache; + }; + module.exports = LRUCache2; + } + }); + + // node_modules/debounce/index.js + var require_debounce = __commonJS({ + "node_modules/debounce/index.js"(exports, module) { + function debounce2(function_, wait = 100, options = {}) { + if (typeof function_ !== "function") { + throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`); + } + if (wait < 0) { + throw new RangeError("`wait` must not be negative."); + } + const { immediate } = typeof options === "boolean" ? { immediate: options } : options; + let storedContext; + let storedArguments; + let timeoutId; + let timestamp; + let result; + function run() { + const callContext = storedContext; + const callArguments = storedArguments; + storedContext = void 0; + storedArguments = void 0; + result = function_.apply(callContext, callArguments); + return result; + } + function later() { + const last = Date.now() - timestamp; + if (last < wait && last >= 0) { + timeoutId = setTimeout(later, wait - last); + } else { + timeoutId = void 0; + if (!immediate) { + result = run(); + } + } + } + const debounced = function(...arguments_) { + if (storedContext && this !== storedContext) { + throw new Error("Debounced method called with different contexts."); + } + storedContext = this; + storedArguments = arguments_; + timestamp = Date.now(); + const callNow = immediate && !timeoutId; + if (!timeoutId) { + timeoutId = setTimeout(later, wait); + } + if (callNow) { + result = run(); + } + return result; + }; + debounced.clear = () => { + if (!timeoutId) { + return; + } + clearTimeout(timeoutId); + timeoutId = void 0; + }; + debounced.flush = () => { + if (!timeoutId) { + return; + } + debounced.trigger(); + }; + debounced.trigger = () => { + result = run(); + debounced.clear(); + }; + return debounced; + } + module.exports.debounce = debounce2; + module.exports = debounce2; + } + }); + + // node_modules/@noble/hashes/esm/crypto.js + var crypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0; + + // node_modules/@noble/hashes/esm/utils.js + var u8a = (a) => a instanceof Uint8Array; + var createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); + var rotr = (word, shift) => word << 32 - shift | word >>> shift; + var isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68; + if (!isLE) + throw new Error("Non little-endian hardware is not supported"); + var hexes = Array.from({ length: 256 }, (v, i2) => i2.toString(16).padStart(2, "0")); + function bytesToHex(bytes3) { + if (!u8a(bytes3)) + throw new Error("Uint8Array expected"); + let hex2 = ""; + for (let i2 = 0; i2 < bytes3.length; i2++) { + hex2 += hexes[bytes3[i2]]; + } + return hex2; + } + function hexToBytes(hex2) { + if (typeof hex2 !== "string") + throw new Error("hex string expected, got " + typeof hex2); + const len = hex2.length; + if (len % 2) + throw new Error("padded hex string expected, got unpadded hex of length " + len); + const array = new Uint8Array(len / 2); + for (let i2 = 0; i2 < array.length; i2++) { + const j = i2 * 2; + const hexByte = hex2.slice(j, j + 2); + const byte = Number.parseInt(hexByte, 16); + if (Number.isNaN(byte) || byte < 0) + throw new Error("Invalid byte sequence"); + array[i2] = byte; + } + return array; + } + function utf8ToBytes(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function toBytes(data) { + if (typeof data === "string") + data = utf8ToBytes(data); + if (!u8a(data)) + throw new Error(`expected Uint8Array, got ${typeof data}`); + return data; + } + var Hash = class { + clone() { + return this._cloneInto(); + } + }; + function wrapConstructor(hashCons) { + const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); + const tmp = hashCons(); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = () => hashCons(); + return hashC; + } + + // node_modules/@scure/base/lib/esm/index.js + function assertNumber(n) { + if (!Number.isSafeInteger(n)) + throw new Error(`Wrong integer: ${n}`); + } + function chain(...args) { + const wrap = (a, b) => (c) => a(b(c)); + const encode = Array.from(args).reverse().reduce((acc, i2) => acc ? wrap(acc, i2.encode) : i2.encode, void 0); + const decode2 = args.reduce((acc, i2) => acc ? wrap(acc, i2.decode) : i2.decode, void 0); + return { encode, decode: decode2 }; + } + function alphabet(alphabet2) { + return { + encode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("alphabet.encode input should be an array of numbers"); + return digits.map((i2) => { + assertNumber(i2); + if (i2 < 0 || i2 >= alphabet2.length) + throw new Error(`Digit index outside alphabet: ${i2} (alphabet: ${alphabet2.length})`); + return alphabet2[i2]; + }); + }, + decode: (input) => { + if (!Array.isArray(input) || input.length && typeof input[0] !== "string") + throw new Error("alphabet.decode input should be array of strings"); + return input.map((letter) => { + if (typeof letter !== "string") + throw new Error(`alphabet.decode: not string element=${letter}`); + const index = alphabet2.indexOf(letter); + if (index === -1) + throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet2}`); + return index; + }); + } + }; + } + function join(separator = "") { + if (typeof separator !== "string") + throw new Error("join separator should be string"); + return { + encode: (from) => { + if (!Array.isArray(from) || from.length && typeof from[0] !== "string") + throw new Error("join.encode input should be array of strings"); + for (let i2 of from) + if (typeof i2 !== "string") + throw new Error(`join.encode: non-string input=${i2}`); + return from.join(separator); + }, + decode: (to) => { + if (typeof to !== "string") + throw new Error("join.decode input should be string"); + return to.split(separator); + } + }; + } + function padding(bits, chr = "=") { + assertNumber(bits); + if (typeof chr !== "string") + throw new Error("padding chr should be string"); + return { + encode(data) { + if (!Array.isArray(data) || data.length && typeof data[0] !== "string") + throw new Error("padding.encode input should be array of strings"); + for (let i2 of data) + if (typeof i2 !== "string") + throw new Error(`padding.encode: non-string input=${i2}`); + while (data.length * bits % 8) + data.push(chr); + return data; + }, + decode(input) { + if (!Array.isArray(input) || input.length && typeof input[0] !== "string") + throw new Error("padding.encode input should be array of strings"); + for (let i2 of input) + if (typeof i2 !== "string") + throw new Error(`padding.decode: non-string input=${i2}`); + let end = input.length; + if (end * bits % 8) + throw new Error("Invalid padding: string should have whole number of bytes"); + for (; end > 0 && input[end - 1] === chr; end--) { + if (!((end - 1) * bits % 8)) + throw new Error("Invalid padding: string has too much padding"); + } + return input.slice(0, end); + } + }; + } + function normalize(fn) { + if (typeof fn !== "function") + throw new Error("normalize fn should be function"); + return { encode: (from) => from, decode: (to) => fn(to) }; + } + function convertRadix(data, from, to) { + if (from < 2) + throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`); + if (to < 2) + throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`); + if (!Array.isArray(data)) + throw new Error("convertRadix: data should be array"); + if (!data.length) + return []; + let pos = 0; + const res = []; + const digits = Array.from(data); + digits.forEach((d) => { + assertNumber(d); + if (d < 0 || d >= from) + throw new Error(`Wrong integer: ${d}`); + }); + while (true) { + let carry = 0; + let done = true; + for (let i2 = pos; i2 < digits.length; i2++) { + const digit = digits[i2]; + const digitBase = from * carry + digit; + if (!Number.isSafeInteger(digitBase) || from * carry / from !== carry || digitBase - digit !== from * carry) { + throw new Error("convertRadix: carry overflow"); + } + carry = digitBase % to; + digits[i2] = Math.floor(digitBase / to); + if (!Number.isSafeInteger(digits[i2]) || digits[i2] * to + carry !== digitBase) + throw new Error("convertRadix: carry overflow"); + if (!done) + continue; + else if (!digits[i2]) + 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 ? a : gcd(b, a % b); + var radix2carry = (from, to) => from + (to - gcd(from, to)); + function convertRadix2(data, from, to, padding2) { + if (!Array.isArray(data)) + throw new Error("convertRadix2: data should be array"); + 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 mask = 2 ** to - 1; + const res = []; + for (const n of data) { + assertNumber(n); + if (n >= 2 ** from) + 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); + carry &= 2 ** pos - 1; + } + carry = carry << to - pos & mask; + if (!padding2 && pos >= from) + throw new Error("Excess padding"); + if (!padding2 && carry) + throw new Error(`Non-zero padding: ${carry}`); + if (padding2 && pos > 0) + res.push(carry >>> 0); + return res; + } + function radix(num) { + assertNumber(num); + return { + encode: (bytes3) => { + if (!(bytes3 instanceof Uint8Array)) + throw new Error("radix.encode input should be Uint8Array"); + return convertRadix(Array.from(bytes3), 2 ** 8, num); + }, + decode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("radix.decode input should be array of strings"); + return Uint8Array.from(convertRadix(digits, num, 2 ** 8)); + } + }; + } + function radix2(bits, revPadding = false) { + assertNumber(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: (bytes3) => { + if (!(bytes3 instanceof Uint8Array)) + throw new Error("radix2.encode input should be Uint8Array"); + return convertRadix2(Array.from(bytes3), 8, bits, !revPadding); + }, + decode: (digits) => { + if (!Array.isArray(digits) || digits.length && typeof digits[0] !== "number") + throw new Error("radix2.decode input should be array of strings"); + return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding)); + } + }; + } + function unsafeWrapper(fn) { + if (typeof fn !== "function") + throw new Error("unsafeWrapper fn should be function"); + 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 base32hex = chain(radix2(5), alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUV"), padding(5), join("")); + var base32crockford = chain(radix2(5), alphabet("0123456789ABCDEFGHJKMNPQRSTVWXYZ"), join(""), normalize((s) => s.toUpperCase().replace(/O/g, "0").replace(/[IL]/g, "1"))); + var base64 = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), padding(6), join("")); + var base64url = chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), padding(6), join("")); + var genBase58 = (abc) => chain(radix(58), alphabet(abc), join("")); + var base58 = genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); + var base58flickr = genBase58("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); + var base58xrp = genBase58("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"); + var XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11]; + var base58xmr = { + encode(data) { + let res = ""; + for (let i2 = 0; i2 < data.length; i2 += 8) { + const block = data.subarray(i2, i2 + 8); + res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], "1"); + } + return res; + }, + decode(str) { + let res = []; + for (let i2 = 0; i2 < str.length; i2 += 11) { + const slice = str.slice(i2, i2 + 11); + const blockLen = XMR_BLOCK_LEN.indexOf(slice.length); + const block = base58.decode(slice); + for (let j = 0; j < block.length - blockLen; j++) { + if (block[j] !== 0) + throw new Error("base58xmr: wrong padding"); + } + res = res.concat(Array.from(block.slice(block.length - blockLen))); + } + return Uint8Array.from(res); + } + }; + 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 % 2 ** 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) { + if (typeof prefix !== "string") + throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`); + if (!Array.isArray(words) || words.length && typeof words[0] !== "number") + throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`); + const actualLength = prefix.length + 7 + words.length; + if (limit !== false && actualLength > limit) + throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`); + prefix = prefix.toLowerCase(); + return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`; + } + function decode2(str, limit = 90) { + if (typeof str !== "string") + throw new Error(`bech32.decode input should be string, not ${typeof str}`); + if (str.length < 8 || limit !== false && str.length > limit) + throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`); + const lowered = str.toLowerCase(); + if (str !== lowered && str !== str.toUpperCase()) + throw new Error(`String must be lowercase or uppercase`); + str = lowered; + const sepIndex = str.lastIndexOf("1"); + if (sepIndex === 0 || sepIndex === -1) + throw new Error(`Letter "1" must be present between prefix and data only`); + const prefix = str.slice(0, sepIndex); + const _words2 = str.slice(sepIndex + 1); + if (_words2.length < 6) + throw new Error("Data must be at least 6 characters long"); + const words = BECH_ALPHABET.decode(_words2).slice(0, -6); + const sum = bechChecksum(prefix, words, ENCODING_CONST); + if (!_words2.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) }; + } + return { encode, decode: decode2, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords }; + } + var bech32 = genBech32("bech32"); + var bech32m = genBech32("bech32m"); + var utf8 = { + encode: (data) => new TextDecoder().decode(data), + decode: (str) => new TextEncoder().encode(str) + }; + var hex = chain(radix2(4), alphabet("0123456789abcdef"), join(""), normalize((s) => { + if (typeof s !== "string" || s.length % 2) + throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`); + return s.toLowerCase(); + })); + var CODERS = { + utf8, + hex, + base16, + base32, + base64, + base64url, + base58, + base58xmr + }; + var coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(", ")}`; + + // node_modules/nostr-tools/lib/esm/nip19.js + var utf8Decoder = new TextDecoder("utf-8"); + var utf8Encoder = new TextEncoder(); + var Bech32MaxSize = 5e3; + function decode(nip19) { + let { prefix, words } = bech32.decode(nip19, 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 "nrelay": { + let tlv = parseTLV(data); + if (!tlv[0]?.[0]) + throw new Error("missing TLV 0 for nrelay"); + return { + type: "nrelay", + data: utf8Decoder.decode(tlv[0][0]) + }; + } + 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 npubEncode(hex2) { + return encodeBytes("npub", hexToBytes(hex2)); + } + function encodeBech32(prefix, data) { + let words = bech32.toWords(data); + return bech32.encode(prefix, words, Bech32MaxSize); + } + function encodeBytes(prefix, bytes3) { + return encodeBech32(prefix, bytes3); + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/_assert.js + function number(n) { + if (!Number.isSafeInteger(n) || n < 0) + throw new Error(`Wrong positive integer: ${n}`); + } + function bytes(b, ...lengths) { + if (!(b instanceof Uint8Array)) + throw new Error("Expected Uint8Array"); + if (lengths.length > 0 && !lengths.includes(b.length)) + throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`); + } + function hash(hash3) { + if (typeof hash3 !== "function" || typeof hash3.create !== "function") + throw new Error("Hash should be wrapped by utils.wrapConstructor"); + number(hash3.outputLen); + number(hash3.blockLen); + } + function exists(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 output(out, instance) { + bytes(out); + const min = instance.outputLen; + if (out.length < min) { + throw new Error(`digestInto() expects output buffer of length at least ${min}`); + } + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/crypto.js + var crypto2 = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0; + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/utils.js + var u8a2 = (a) => a instanceof Uint8Array; + var createView2 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); + var rotr2 = (word, shift) => word << 32 - shift | word >>> shift; + var isLE2 = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68; + if (!isLE2) + throw new Error("Non little-endian hardware is not supported"); + function utf8ToBytes2(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function toBytes2(data) { + if (typeof data === "string") + data = utf8ToBytes2(data); + if (!u8a2(data)) + throw new Error(`expected Uint8Array, got ${typeof data}`); + return data; + } + function concatBytes2(...arrays) { + const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0)); + let pad = 0; + arrays.forEach((a) => { + if (!u8a2(a)) + throw new Error("Uint8Array expected"); + r.set(a, pad); + pad += a.length; + }); + return r; + } + var Hash2 = class { + clone() { + return this._cloneInto(); + } + }; + var toStr = {}.toString; + function wrapConstructor2(hashCons) { + const hashC = (msg) => hashCons().update(toBytes2(msg)).digest(); + const tmp = hashCons(); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = () => hashCons(); + return hashC; + } + function randomBytes(bytesLength = 32) { + if (crypto2 && typeof crypto2.getRandomValues === "function") { + return crypto2.getRandomValues(new Uint8Array(bytesLength)); + } + throw new Error("crypto.getRandomValues must be defined"); + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/_sha2.js + function setBigUint64(view, byteOffset, value, isLE3) { + if (typeof view.setBigUint64 === "function") + return view.setBigUint64(byteOffset, value, isLE3); + const _32n = BigInt(32); + const _u32_max = BigInt(4294967295); + const wh = Number(value >> _32n & _u32_max); + const wl = Number(value & _u32_max); + const h = isLE3 ? 4 : 0; + const l = isLE3 ? 0 : 4; + view.setUint32(byteOffset + h, wh, isLE3); + view.setUint32(byteOffset + l, wl, isLE3); + } + var SHA2 = class extends Hash2 { + constructor(blockLen, outputLen, padOffset, isLE3) { + super(); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE3; + this.finished = false; + this.length = 0; + this.pos = 0; + this.destroyed = false; + this.buffer = new Uint8Array(blockLen); + this.view = createView2(this.buffer); + } + update(data) { + exists(this); + const { view, buffer, blockLen } = this; + data = toBytes2(data); + const len = data.length; + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + if (take === blockLen) { + const dataView = createView2(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) { + exists(this); + output(out, this); + this.finished = true; + const { buffer, view, blockLen, isLE: isLE3 } = this; + let { pos } = this; + buffer[pos++] = 128; + this.buffer.subarray(pos).fill(0); + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + for (let i2 = pos; i2 < blockLen; i2++) + buffer[i2] = 0; + setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE3); + this.process(view, 0); + const oview = createView2(out); + const len = this.outputLen; + if (len % 4) + throw new Error("_sha2: outputLen should 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], isLE3); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to || (to = new this.constructor()); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.length = length; + to.pos = pos; + to.finished = finished; + to.destroyed = destroyed; + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + }; + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha256.js + var Chi = (a, b, c) => a & b ^ ~a & c; + var Maj = (a, b, c) => a & b ^ a & c ^ b & c; + var SHA256_K = /* @__PURE__ */ new Uint32Array([ + 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 IV = /* @__PURE__ */ new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 + ]); + var SHA256_W = /* @__PURE__ */ new Uint32Array(64); + var SHA256 = class extends SHA2 { + constructor() { + super(64, 32, 8, false); + this.A = IV[0] | 0; + this.B = IV[1] | 0; + this.C = IV[2] | 0; + this.D = IV[3] | 0; + this.E = IV[4] | 0; + this.F = IV[5] | 0; + this.G = IV[6] | 0; + this.H = IV[7] | 0; + } + 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 = rotr2(W15, 7) ^ rotr2(W15, 18) ^ W15 >>> 3; + const s1 = rotr2(W2, 17) ^ rotr2(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 = rotr2(E, 6) ^ rotr2(E, 11) ^ rotr2(E, 25); + const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i2] + SHA256_W[i2] | 0; + const sigma0 = rotr2(A, 2) ^ rotr2(A, 13) ^ rotr2(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() { + SHA256_W.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0); + this.buffer.fill(0); + } + }; + var sha256 = /* @__PURE__ */ wrapConstructor2(() => new SHA256()); + + // node_modules/@noble/curves/esm/abstract/utils.js + var utils_exports = {}; + __export(utils_exports, { + bitGet: () => bitGet, + bitLen: () => bitLen, + bitMask: () => bitMask, + bitSet: () => bitSet, + bytesToHex: () => bytesToHex2, + bytesToNumberBE: () => bytesToNumberBE, + bytesToNumberLE: () => bytesToNumberLE, + concatBytes: () => concatBytes3, + createHmacDrbg: () => createHmacDrbg, + ensureBytes: () => ensureBytes, + equalBytes: () => equalBytes, + hexToBytes: () => hexToBytes2, + hexToNumber: () => hexToNumber, + numberToBytesBE: () => numberToBytesBE, + numberToBytesLE: () => numberToBytesLE, + numberToHexUnpadded: () => numberToHexUnpadded, + numberToVarBytesBE: () => numberToVarBytesBE, + utf8ToBytes: () => utf8ToBytes3, + validateObject: () => validateObject + }); + var _0n = BigInt(0); + var _1n = BigInt(1); + var _2n = BigInt(2); + var u8a3 = (a) => a instanceof Uint8Array; + var hexes2 = /* @__PURE__ */ Array.from({ length: 256 }, (_, i2) => i2.toString(16).padStart(2, "0")); + function bytesToHex2(bytes3) { + if (!u8a3(bytes3)) + throw new Error("Uint8Array expected"); + let hex2 = ""; + for (let i2 = 0; i2 < bytes3.length; i2++) { + hex2 += hexes2[bytes3[i2]]; + } + return hex2; + } + function numberToHexUnpadded(num) { + const hex2 = num.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 BigInt(hex2 === "" ? "0" : `0x${hex2}`); + } + function hexToBytes2(hex2) { + if (typeof hex2 !== "string") + throw new Error("hex string expected, got " + typeof hex2); + const len = hex2.length; + if (len % 2) + throw new Error("padded hex string expected, got unpadded hex of length " + len); + const array = new Uint8Array(len / 2); + for (let i2 = 0; i2 < array.length; i2++) { + const j = i2 * 2; + const hexByte = hex2.slice(j, j + 2); + const byte = Number.parseInt(hexByte, 16); + if (Number.isNaN(byte) || byte < 0) + throw new Error("Invalid byte sequence"); + array[i2] = byte; + } + return array; + } + function bytesToNumberBE(bytes3) { + return hexToNumber(bytesToHex2(bytes3)); + } + function bytesToNumberLE(bytes3) { + if (!u8a3(bytes3)) + throw new Error("Uint8Array expected"); + return hexToNumber(bytesToHex2(Uint8Array.from(bytes3).reverse())); + } + function numberToBytesBE(n, len) { + return hexToBytes2(n.toString(16).padStart(len * 2, "0")); + } + function numberToBytesLE(n, len) { + return numberToBytesBE(n, len).reverse(); + } + function numberToVarBytesBE(n) { + return hexToBytes2(numberToHexUnpadded(n)); + } + function ensureBytes(title, hex2, expectedLength) { + let res; + if (typeof hex2 === "string") { + try { + res = hexToBytes2(hex2); + } catch (e) { + throw new Error(`${title} must be valid hex string, got "${hex2}". Cause: ${e}`); + } + } else if (u8a3(hex2)) { + res = Uint8Array.from(hex2); + } else { + throw new Error(`${title} must be hex string or Uint8Array`); + } + const len = res.length; + if (typeof expectedLength === "number" && len !== expectedLength) + throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`); + return res; + } + function concatBytes3(...arrays) { + const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0)); + let pad = 0; + arrays.forEach((a) => { + if (!u8a3(a)) + throw new Error("Uint8Array expected"); + r.set(a, pad); + pad += a.length; + }); + return r; + } + function equalBytes(b1, b2) { + if (b1.length !== b2.length) + return false; + for (let i2 = 0; i2 < b1.length; i2++) + if (b1[i2] !== b2[i2]) + return false; + return true; + } + function utf8ToBytes3(str) { + if (typeof str !== "string") + throw new Error(`utf8ToBytes expected string, got ${typeof str}`); + return new Uint8Array(new TextEncoder().encode(str)); + } + function bitLen(n) { + let len; + for (len = 0; n > _0n; n >>= _1n, len += 1) + ; + return len; + } + function bitGet(n, pos) { + return n >> BigInt(pos) & _1n; + } + var bitSet = (n, pos, value) => { + return n | (value ? _1n : _0n) << BigInt(pos); + }; + var bitMask = (n) => (_2n << BigInt(n - 1)) - _1n; + var u8n = (data) => new Uint8Array(data); + var u8fr = (arr) => Uint8Array.from(arr); + function createHmacDrbg(hashLen, qByteLen, hmacFn) { + if (typeof hashLen !== "number" || hashLen < 2) + throw new Error("hashLen must be a number"); + if (typeof qByteLen !== "number" || qByteLen < 2) + throw new Error("qByteLen must be a number"); + if (typeof hmacFn !== "function") + throw new Error("hmacFn must be a function"); + let v = u8n(hashLen); + let k = u8n(hashLen); + let i2 = 0; + const reset = () => { + v.fill(1); + k.fill(0); + i2 = 0; + }; + const h = (...b) => hmacFn(k, v, ...b); + const reseed = (seed = u8n()) => { + k = h(u8fr([0]), seed); + v = h(); + if (seed.length === 0) + return; + k = h(u8fr([1]), seed); + v = h(); + }; + const gen = () => { + if (i2++ >= 1e3) + throw new Error("drbg: tried 1000 values"); + let len = 0; + const out = []; + while (len < qByteLen) { + v = h(); + const sl = v.slice(); + out.push(sl); + len += v.length; + } + return concatBytes3(...out); + }; + const genUntil = (seed, pred) => { + reset(); + reseed(seed); + let res = void 0; + while (!(res = pred(gen()))) + reseed(); + reset(); + return res; + }; + return genUntil; + } + var validatorFns = { + bigint: (val) => typeof val === "bigint", + function: (val) => typeof val === "function", + boolean: (val) => typeof val === "boolean", + string: (val) => typeof val === "string", + stringOrUint8Array: (val) => typeof val === "string" || val instanceof Uint8Array, + isSafeInteger: (val) => Number.isSafeInteger(val), + array: (val) => Array.isArray(val), + field: (val, object) => object.Fp.isValid(val), + hash: (val) => typeof val === "function" && Number.isSafeInteger(val.outputLen) + }; + function validateObject(object, validators, optValidators = {}) { + const checkField = (fieldName, type, isOptional) => { + const checkVal = validatorFns[type]; + if (typeof checkVal !== "function") + throw new Error(`Invalid validator "${type}", expected function`); + const val = object[fieldName]; + if (isOptional && val === void 0) + return; + if (!checkVal(val, object)) { + throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`); + } + }; + for (const [fieldName, type] of Object.entries(validators)) + checkField(fieldName, type, false); + for (const [fieldName, type] of Object.entries(optValidators)) + checkField(fieldName, type, true); + return object; + } + + // node_modules/@noble/curves/esm/abstract/modular.js + var _0n2 = BigInt(0); + var _1n2 = BigInt(1); + var _2n2 = BigInt(2); + var _3n = BigInt(3); + var _4n = BigInt(4); + var _5n = BigInt(5); + var _8n = BigInt(8); + var _9n = BigInt(9); + var _16n = BigInt(16); + function mod(a, b) { + const result = a % b; + return result >= _0n2 ? result : b + result; + } + function pow(num, power, modulo) { + if (modulo <= _0n2 || power < _0n2) + throw new Error("Expected power/modulo > 0"); + if (modulo === _1n2) + return _0n2; + let res = _1n2; + while (power > _0n2) { + if (power & _1n2) + res = res * num % modulo; + num = num * num % modulo; + power >>= _1n2; + } + return res; + } + function pow2(x, power, modulo) { + let res = x; + while (power-- > _0n2) { + res *= res; + res %= modulo; + } + return res; + } + function invert(number3, modulo) { + if (number3 === _0n2 || modulo <= _0n2) { + throw new Error(`invert: expected positive integers, got n=${number3} mod=${modulo}`); + } + let a = mod(number3, 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 tonelliShanks(P) { + const legendreC = (P - _1n2) / _2n2; + let Q, S, Z; + for (Q = P - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++) + ; + for (Z = _2n2; Z < P && pow(Z, legendreC, P) !== P - _1n2; Z++) + ; + if (S === 1) { + const p1div4 = (P + _1n2) / _4n; + return function tonelliFast(Fp2, n) { + const root = Fp2.pow(n, p1div4); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + const Q1div2 = (Q + _1n2) / _2n2; + return function tonelliSlow(Fp2, n) { + if (Fp2.pow(n, legendreC) === Fp2.neg(Fp2.ONE)) + throw new Error("Cannot find square root"); + let r = S; + let g = Fp2.pow(Fp2.mul(Fp2.ONE, Z), Q); + let x = Fp2.pow(n, Q1div2); + let b = Fp2.pow(n, Q); + while (!Fp2.eql(b, Fp2.ONE)) { + if (Fp2.eql(b, Fp2.ZERO)) + return Fp2.ZERO; + let m = 1; + for (let t2 = Fp2.sqr(b); m < r; m++) { + if (Fp2.eql(t2, Fp2.ONE)) + break; + t2 = Fp2.sqr(t2); + } + const ge2 = Fp2.pow(g, _1n2 << BigInt(r - m - 1)); + g = Fp2.sqr(ge2); + x = Fp2.mul(x, ge2); + b = Fp2.mul(b, g); + r = m; + } + return x; + }; + } + function FpSqrt(P) { + if (P % _4n === _3n) { + const p1div4 = (P + _1n2) / _4n; + return function sqrt3mod4(Fp2, n) { + const root = Fp2.pow(n, p1div4); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + if (P % _8n === _5n) { + const c1 = (P - _5n) / _8n; + return function sqrt5mod8(Fp2, n) { + const n2 = Fp2.mul(n, _2n2); + const v = Fp2.pow(n2, c1); + const nv = Fp2.mul(n, v); + const i2 = Fp2.mul(Fp2.mul(nv, _2n2), v); + const root = Fp2.mul(nv, Fp2.sub(i2, Fp2.ONE)); + if (!Fp2.eql(Fp2.sqr(root), n)) + throw new Error("Cannot find square root"); + return root; + }; + } + if (P % _16n === _9n) { + } + 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", + MASK: "bigint", + BYTES: "isSafeInteger", + BITS: "isSafeInteger" + }; + const opts = FIELD_FIELDS.reduce((map, val) => { + map[val] = "function"; + return map; + }, initial); + return validateObject(field, opts); + } + function FpPow(f, num, power) { + if (power < _0n2) + throw new Error("Expected power > 0"); + if (power === _0n2) + return f.ONE; + if (power === _1n2) + return num; + let p = f.ONE; + let d = num; + while (power > _0n2) { + if (power & _1n2) + p = f.mul(p, d); + d = f.sqr(d); + power >>= _1n2; + } + return p; + } + function FpInvertBatch(f, nums) { + const tmp = new Array(nums.length); + const lastMultiplied = nums.reduce((acc, num, i2) => { + if (f.is0(num)) + return acc; + tmp[i2] = acc; + return f.mul(acc, num); + }, f.ONE); + const inverted = f.inv(lastMultiplied); + nums.reduceRight((acc, num, i2) => { + if (f.is0(num)) + return acc; + tmp[i2] = f.mul(acc, tmp[i2]); + return f.mul(acc, num); + }, inverted); + return tmp; + } + function nLength(n, nBitLength) { + const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length; + const nByteLength = Math.ceil(_nBitLength / 8); + return { nBitLength: _nBitLength, nByteLength }; + } + function Field(ORDER, bitLen2, isLE3 = false, redef = {}) { + if (ORDER <= _0n2) + throw new Error(`Expected Field ORDER > 0, got ${ORDER}`); + const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2); + if (BYTES > 2048) + throw new Error("Field lengths over 2048 bytes are not supported"); + const sqrtP = FpSqrt(ORDER); + const f = Object.freeze({ + ORDER, + BITS, + BYTES, + MASK: bitMask(BITS), + ZERO: _0n2, + ONE: _1n2, + create: (num) => mod(num, ORDER), + isValid: (num) => { + if (typeof num !== "bigint") + throw new Error(`Invalid field element: expected bigint, got ${typeof num}`); + return _0n2 <= num && num < ORDER; + }, + is0: (num) => num === _0n2, + isOdd: (num) => (num & _1n2) === _1n2, + neg: (num) => mod(-num, ORDER), + eql: (lhs, rhs) => lhs === rhs, + sqr: (num) => mod(num * num, ORDER), + add: (lhs, rhs) => mod(lhs + rhs, ORDER), + sub: (lhs, rhs) => mod(lhs - rhs, ORDER), + mul: (lhs, rhs) => mod(lhs * rhs, ORDER), + pow: (num, power) => FpPow(f, num, power), + div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER), + sqrN: (num) => num * num, + addN: (lhs, rhs) => lhs + rhs, + subN: (lhs, rhs) => lhs - rhs, + mulN: (lhs, rhs) => lhs * rhs, + inv: (num) => invert(num, ORDER), + sqrt: redef.sqrt || ((n) => sqrtP(f, n)), + invertBatch: (lst) => FpInvertBatch(f, lst), + cmov: (a, b, c) => c ? b : a, + toBytes: (num) => isLE3 ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES), + fromBytes: (bytes3) => { + if (bytes3.length !== BYTES) + throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes3.length}`); + return isLE3 ? bytesToNumberLE(bytes3) : bytesToNumberBE(bytes3); + } + }); + return Object.freeze(f); + } + 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, isLE3 = false) { + 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 num = isLE3 ? bytesToNumberBE(key) : bytesToNumberLE(key); + const reduced = mod(num, fieldOrder - _1n2) + _1n2; + return isLE3 ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen); + } + + // node_modules/@noble/curves/esm/abstract/curve.js + var _0n3 = BigInt(0); + var _1n3 = BigInt(1); + function wNAF(c, bits) { + const constTimeNegate = (condition, item) => { + const neg = item.negate(); + return condition ? neg : item; + }; + const opts = (W) => { + const windows = Math.ceil(bits / W) + 1; + const windowSize = 2 ** (W - 1); + return { windows, windowSize }; + }; + return { + constTimeNegate, + unsafeLadder(elm, n) { + let p = c.ZERO; + let d = elm; + while (n > _0n3) { + if (n & _1n3) + p = p.add(d); + d = d.double(); + n >>= _1n3; + } + return p; + }, + precomputeWindow(elm, W) { + const { windows, windowSize } = opts(W); + const points = []; + let p = elm; + 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) { + const { windows, windowSize } = opts(W); + let p = c.ZERO; + let f = c.BASE; + const mask = BigInt(2 ** W - 1); + const maxNumber = 2 ** W; + const shiftBy = BigInt(W); + for (let window2 = 0; window2 < windows; window2++) { + const offset = window2 * windowSize; + let wbits = Number(n & mask); + n >>= shiftBy; + if (wbits > windowSize) { + wbits -= maxNumber; + n += _1n3; + } + const offset1 = offset; + const offset2 = offset + Math.abs(wbits) - 1; + const cond1 = window2 % 2 !== 0; + const cond2 = wbits < 0; + if (wbits === 0) { + f = f.add(constTimeNegate(cond1, precomputes[offset1])); + } else { + p = p.add(constTimeNegate(cond2, precomputes[offset2])); + } + } + return { p, f }; + }, + wNAFCached(P, precomputesMap, n, transform) { + const W = P._WINDOW_SIZE || 1; + let comp = precomputesMap.get(P); + if (!comp) { + comp = this.precomputeWindow(P, W); + if (W !== 1) { + precomputesMap.set(P, transform(comp)); + } + } + return this.wNAF(W, comp, n); + } + }; + } + function validateBasic(curve) { + validateField(curve.Fp); + validateObject(curve, { + n: "bigint", + h: "bigint", + Gx: "field", + Gy: "field" + }, { + nBitLength: "isSafeInteger", + nByteLength: "isSafeInteger" + }); + return Object.freeze({ + ...nLength(curve.n, curve.nBitLength), + ...curve, + ...{ p: curve.Fp.ORDER } + }); + } + + // node_modules/@noble/curves/esm/abstract/weierstrass.js + function validatePointOpts(curve) { + const opts = validateBasic(curve); + validateObject(opts, { + a: "field", + b: "field" + }, { + allowedPrivateKeyLengths: "array", + wrapPrivateKey: "boolean", + isTorsionFree: "function", + clearCofactor: "function", + allowInfinityPoint: "boolean", + fromBytes: "function", + toBytes: "function" + }); + const { endo, Fp: Fp2, a } = opts; + if (endo) { + if (!Fp2.eql(a, Fp2.ZERO)) { + throw new Error("Endomorphism can only be defined for Koblitz curves that have a=0"); + } + if (typeof endo !== "object" || typeof endo.beta !== "bigint" || typeof endo.splitScalar !== "function") { + throw new Error("Expected endomorphism with beta: bigint and splitScalar: function"); + } + } + return Object.freeze({ ...opts }); + } + var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports; + var DER = { + Err: class DERErr extends Error { + constructor(m = "") { + super(m); + } + }, + _parseInt(data) { + const { Err: E } = DER; + if (data.length < 2 || data[0] !== 2) + throw new E("Invalid signature integer tag"); + const len = data[1]; + const res = data.subarray(2, len + 2); + if (!len || res.length !== len) + throw new E("Invalid signature integer: wrong length"); + if (res[0] & 128) + throw new E("Invalid signature integer: negative"); + if (res[0] === 0 && !(res[1] & 128)) + throw new E("Invalid signature integer: unnecessary leading zero"); + return { d: b2n(res), l: data.subarray(len + 2) }; + }, + toSig(hex2) { + const { Err: E } = DER; + const data = typeof hex2 === "string" ? h2b(hex2) : hex2; + if (!(data instanceof Uint8Array)) + throw new Error("ui8a expected"); + let l = data.length; + if (l < 2 || data[0] != 48) + throw new E("Invalid signature tag"); + if (data[1] !== l - 2) + throw new E("Invalid signature: incorrect length"); + const { d: r, l: sBytes } = DER._parseInt(data.subarray(2)); + const { d: s, l: rBytesLeft } = DER._parseInt(sBytes); + if (rBytesLeft.length) + throw new E("Invalid signature: left bytes after parsing"); + return { r, s }; + }, + hexFromSig(sig) { + const slice = (s2) => Number.parseInt(s2[0], 16) & 8 ? "00" + s2 : s2; + const h = (num) => { + const hex2 = num.toString(16); + return hex2.length & 1 ? `0${hex2}` : hex2; + }; + const s = slice(h(sig.s)); + const r = slice(h(sig.r)); + const shl = s.length / 2; + const rhl = r.length / 2; + const sl = h(shl); + const rl = h(rhl); + return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`; + } + }; + var _0n4 = BigInt(0); + var _1n4 = BigInt(1); + var _2n3 = BigInt(2); + var _3n2 = BigInt(3); + var _4n2 = BigInt(4); + function weierstrassPoints(opts) { + const CURVE = validatePointOpts(opts); + const { Fp: Fp2 } = CURVE; + const toBytes3 = CURVE.toBytes || ((_c, point, _isCompressed) => { + const a = point.toAffine(); + return concatBytes3(Uint8Array.from([4]), Fp2.toBytes(a.x), Fp2.toBytes(a.y)); + }); + const fromBytes = CURVE.fromBytes || ((bytes3) => { + const tail = bytes3.subarray(1); + const x = Fp2.fromBytes(tail.subarray(0, Fp2.BYTES)); + const y = Fp2.fromBytes(tail.subarray(Fp2.BYTES, 2 * Fp2.BYTES)); + return { x, y }; + }); + function weierstrassEquation(x) { + const { a, b } = CURVE; + const x2 = Fp2.sqr(x); + const x3 = Fp2.mul(x2, x); + return Fp2.add(Fp2.add(x3, Fp2.mul(x, a)), b); + } + if (!Fp2.eql(Fp2.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx))) + throw new Error("bad generator point: equation left != right"); + function isWithinCurveOrder(num) { + return typeof num === "bigint" && _0n4 < num && num < CURVE.n; + } + function assertGE(num) { + if (!isWithinCurveOrder(num)) + throw new Error("Expected valid bigint: 0 < bigint < curve.n"); + } + function normPrivateKeyToScalar(key) { + const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE; + if (lengths && typeof key !== "bigint") { + if (key instanceof Uint8Array) + key = bytesToHex2(key); + if (typeof key !== "string" || !lengths.includes(key.length)) + throw new Error("Invalid key"); + key = key.padStart(nByteLength * 2, "0"); + } + let num; + try { + num = typeof key === "bigint" ? key : bytesToNumberBE(ensureBytes("private key", key, nByteLength)); + } catch (error) { + throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`); + } + if (wrapPrivateKey) + num = mod(num, n); + assertGE(num); + return num; + } + const pointPrecomputes = /* @__PURE__ */ new Map(); + function assertPrjPoint(other) { + if (!(other instanceof Point2)) + throw new Error("ProjectivePoint expected"); + } + class Point2 { + constructor(px, py, pz) { + this.px = px; + this.py = py; + this.pz = pz; + if (px == null || !Fp2.isValid(px)) + throw new Error("x required"); + if (py == null || !Fp2.isValid(py)) + throw new Error("y required"); + if (pz == null || !Fp2.isValid(pz)) + throw new Error("z required"); + } + static fromAffine(p) { + const { x, y } = p || {}; + if (!p || !Fp2.isValid(x) || !Fp2.isValid(y)) + throw new Error("invalid affine point"); + if (p instanceof Point2) + throw new Error("projective point not allowed"); + const is0 = (i2) => Fp2.eql(i2, Fp2.ZERO); + if (is0(x) && is0(y)) + return Point2.ZERO; + return new Point2(x, y, Fp2.ONE); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + static normalizeZ(points) { + const toInv = Fp2.invertBatch(points.map((p) => p.pz)); + return points.map((p, i2) => p.toAffine(toInv[i2])).map(Point2.fromAffine); + } + static fromHex(hex2) { + const P = Point2.fromAffine(fromBytes(ensureBytes("pointHex", hex2))); + P.assertValidity(); + return P; + } + static fromPrivateKey(privateKey) { + return Point2.BASE.multiply(normPrivateKeyToScalar(privateKey)); + } + _setWindowSize(windowSize) { + this._WINDOW_SIZE = windowSize; + pointPrecomputes.delete(this); + } + assertValidity() { + if (this.is0()) { + if (CURVE.allowInfinityPoint && !Fp2.is0(this.py)) + return; + throw new Error("bad point: ZERO"); + } + const { x, y } = this.toAffine(); + if (!Fp2.isValid(x) || !Fp2.isValid(y)) + throw new Error("bad point: x or y not FE"); + const left = Fp2.sqr(y); + const right = weierstrassEquation(x); + if (!Fp2.eql(left, right)) + throw new Error("bad point: equation left != right"); + if (!this.isTorsionFree()) + throw new Error("bad point: not in prime-order subgroup"); + } + hasEvenY() { + const { y } = this.toAffine(); + if (Fp2.isOdd) + return !Fp2.isOdd(y); + throw new Error("Field doesn't support isOdd"); + } + equals(other) { + assertPrjPoint(other); + const { px: X1, py: Y1, pz: Z1 } = this; + const { px: X2, py: Y2, pz: Z2 } = other; + const U1 = Fp2.eql(Fp2.mul(X1, Z2), Fp2.mul(X2, Z1)); + const U2 = Fp2.eql(Fp2.mul(Y1, Z2), Fp2.mul(Y2, Z1)); + return U1 && U2; + } + negate() { + return new Point2(this.px, Fp2.neg(this.py), this.pz); + } + double() { + const { a, b } = CURVE; + const b3 = Fp2.mul(b, _3n2); + const { px: X1, py: Y1, pz: Z1 } = this; + let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO; + let t0 = Fp2.mul(X1, X1); + let t1 = Fp2.mul(Y1, Y1); + let t2 = Fp2.mul(Z1, Z1); + let t3 = Fp2.mul(X1, Y1); + t3 = Fp2.add(t3, t3); + Z3 = Fp2.mul(X1, Z1); + Z3 = Fp2.add(Z3, Z3); + X3 = Fp2.mul(a, Z3); + Y3 = Fp2.mul(b3, t2); + Y3 = Fp2.add(X3, Y3); + X3 = Fp2.sub(t1, Y3); + Y3 = Fp2.add(t1, Y3); + Y3 = Fp2.mul(X3, Y3); + X3 = Fp2.mul(t3, X3); + Z3 = Fp2.mul(b3, Z3); + t2 = Fp2.mul(a, t2); + t3 = Fp2.sub(t0, t2); + t3 = Fp2.mul(a, t3); + t3 = Fp2.add(t3, Z3); + Z3 = Fp2.add(t0, t0); + t0 = Fp2.add(Z3, t0); + t0 = Fp2.add(t0, t2); + t0 = Fp2.mul(t0, t3); + Y3 = Fp2.add(Y3, t0); + t2 = Fp2.mul(Y1, Z1); + t2 = Fp2.add(t2, t2); + t0 = Fp2.mul(t2, t3); + X3 = Fp2.sub(X3, t0); + Z3 = Fp2.mul(t2, t1); + Z3 = Fp2.add(Z3, Z3); + Z3 = Fp2.add(Z3, Z3); + return new Point2(X3, Y3, Z3); + } + add(other) { + assertPrjPoint(other); + const { px: X1, py: Y1, pz: Z1 } = this; + const { px: X2, py: Y2, pz: Z2 } = other; + let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO; + const a = CURVE.a; + const b3 = Fp2.mul(CURVE.b, _3n2); + let t0 = Fp2.mul(X1, X2); + let t1 = Fp2.mul(Y1, Y2); + let t2 = Fp2.mul(Z1, Z2); + let t3 = Fp2.add(X1, Y1); + let t4 = Fp2.add(X2, Y2); + t3 = Fp2.mul(t3, t4); + t4 = Fp2.add(t0, t1); + t3 = Fp2.sub(t3, t4); + t4 = Fp2.add(X1, Z1); + let t5 = Fp2.add(X2, Z2); + t4 = Fp2.mul(t4, t5); + t5 = Fp2.add(t0, t2); + t4 = Fp2.sub(t4, t5); + t5 = Fp2.add(Y1, Z1); + X3 = Fp2.add(Y2, Z2); + t5 = Fp2.mul(t5, X3); + X3 = Fp2.add(t1, t2); + t5 = Fp2.sub(t5, X3); + Z3 = Fp2.mul(a, t4); + X3 = Fp2.mul(b3, t2); + Z3 = Fp2.add(X3, Z3); + X3 = Fp2.sub(t1, Z3); + Z3 = Fp2.add(t1, Z3); + Y3 = Fp2.mul(X3, Z3); + t1 = Fp2.add(t0, t0); + t1 = Fp2.add(t1, t0); + t2 = Fp2.mul(a, t2); + t4 = Fp2.mul(b3, t4); + t1 = Fp2.add(t1, t2); + t2 = Fp2.sub(t0, t2); + t2 = Fp2.mul(a, t2); + t4 = Fp2.add(t4, t2); + t0 = Fp2.mul(t1, t4); + Y3 = Fp2.add(Y3, t0); + t0 = Fp2.mul(t5, t4); + X3 = Fp2.mul(t3, X3); + X3 = Fp2.sub(X3, t0); + t0 = Fp2.mul(t3, t1); + Z3 = Fp2.mul(t5, Z3); + Z3 = Fp2.add(Z3, t0); + return new Point2(X3, Y3, Z3); + } + subtract(other) { + return this.add(other.negate()); + } + is0() { + return this.equals(Point2.ZERO); + } + wNAF(n) { + return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => { + const toInv = Fp2.invertBatch(comp.map((p) => p.pz)); + return comp.map((p, i2) => p.toAffine(toInv[i2])).map(Point2.fromAffine); + }); + } + multiplyUnsafe(n) { + const I = Point2.ZERO; + if (n === _0n4) + return I; + assertGE(n); + if (n === _1n4) + return this; + const { endo } = CURVE; + if (!endo) + return wnaf.unsafeLadder(this, n); + let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n); + let k1p = I; + let k2p = I; + let d = this; + while (k1 > _0n4 || k2 > _0n4) { + if (k1 & _1n4) + k1p = k1p.add(d); + if (k2 & _1n4) + k2p = k2p.add(d); + d = d.double(); + k1 >>= _1n4; + k2 >>= _1n4; + } + if (k1neg) + k1p = k1p.negate(); + if (k2neg) + k2p = k2p.negate(); + k2p = new Point2(Fp2.mul(k2p.px, endo.beta), k2p.py, k2p.pz); + return k1p.add(k2p); + } + multiply(scalar) { + assertGE(scalar); + let n = scalar; + let point, fake; + const { endo } = CURVE; + if (endo) { + const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n); + let { p: k1p, f: f1p } = this.wNAF(k1); + let { p: k2p, f: f2p } = this.wNAF(k2); + k1p = wnaf.constTimeNegate(k1neg, k1p); + k2p = wnaf.constTimeNegate(k2neg, k2p); + k2p = new Point2(Fp2.mul(k2p.px, endo.beta), k2p.py, k2p.pz); + point = k1p.add(k2p); + fake = f1p.add(f2p); + } else { + const { p, f } = this.wNAF(n); + point = p; + fake = f; + } + return Point2.normalizeZ([point, fake])[0]; + } + multiplyAndAddUnsafe(Q, a, b) { + const G = Point2.BASE; + const mul = (P, a2) => a2 === _0n4 || a2 === _1n4 || !P.equals(G) ? P.multiplyUnsafe(a2) : P.multiply(a2); + const sum = mul(this, a).add(mul(Q, b)); + return sum.is0() ? void 0 : sum; + } + toAffine(iz) { + const { px: x, py: y, pz: z } = this; + const is0 = this.is0(); + if (iz == null) + iz = is0 ? Fp2.ONE : Fp2.inv(z); + const ax = Fp2.mul(x, iz); + const ay = Fp2.mul(y, iz); + const zz = Fp2.mul(z, iz); + if (is0) + return { x: Fp2.ZERO, y: Fp2.ZERO }; + if (!Fp2.eql(zz, Fp2.ONE)) + throw new Error("invZ was invalid"); + return { x: ax, y: ay }; + } + isTorsionFree() { + const { h: cofactor, isTorsionFree } = CURVE; + if (cofactor === _1n4) + return true; + if (isTorsionFree) + return isTorsionFree(Point2, this); + throw new Error("isTorsionFree() has not been declared for the elliptic curve"); + } + clearCofactor() { + const { h: cofactor, clearCofactor } = CURVE; + if (cofactor === _1n4) + return this; + if (clearCofactor) + return clearCofactor(Point2, this); + return this.multiplyUnsafe(CURVE.h); + } + toRawBytes(isCompressed = true) { + this.assertValidity(); + return toBytes3(Point2, this, isCompressed); + } + toHex(isCompressed = true) { + return bytesToHex2(this.toRawBytes(isCompressed)); + } + } + Point2.BASE = new Point2(CURVE.Gx, CURVE.Gy, Fp2.ONE); + Point2.ZERO = new Point2(Fp2.ZERO, Fp2.ONE, Fp2.ZERO); + const _bits = CURVE.nBitLength; + const wnaf = wNAF(Point2, CURVE.endo ? Math.ceil(_bits / 2) : _bits); + return { + CURVE, + ProjectivePoint: Point2, + normPrivateKeyToScalar, + weierstrassEquation, + isWithinCurveOrder + }; + } + function validateOpts(curve) { + const opts = validateBasic(curve); + validateObject(opts, { + hash: "hash", + hmac: "function", + randomBytes: "function" + }, { + bits2int: "function", + bits2int_modN: "function", + lowS: "boolean" + }); + return Object.freeze({ lowS: true, ...opts }); + } + function weierstrass(curveDef) { + const CURVE = validateOpts(curveDef); + const { Fp: Fp2, n: CURVE_ORDER } = CURVE; + const compressedLen = Fp2.BYTES + 1; + const uncompressedLen = 2 * Fp2.BYTES + 1; + function isValidFieldElement(num) { + return _0n4 < num && num < Fp2.ORDER; + } + function modN2(a) { + return mod(a, CURVE_ORDER); + } + function invN(a) { + return invert(a, CURVE_ORDER); + } + const { ProjectivePoint: Point2, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder } = weierstrassPoints({ + ...CURVE, + toBytes(_c, point, isCompressed) { + const a = point.toAffine(); + const x = Fp2.toBytes(a.x); + const cat = concatBytes3; + if (isCompressed) { + return cat(Uint8Array.from([point.hasEvenY() ? 2 : 3]), x); + } else { + return cat(Uint8Array.from([4]), x, Fp2.toBytes(a.y)); + } + }, + fromBytes(bytes3) { + const len = bytes3.length; + const head = bytes3[0]; + const tail = bytes3.subarray(1); + if (len === compressedLen && (head === 2 || head === 3)) { + const x = bytesToNumberBE(tail); + if (!isValidFieldElement(x)) + throw new Error("Point is not on curve"); + const y2 = weierstrassEquation(x); + let y = Fp2.sqrt(y2); + const isYOdd = (y & _1n4) === _1n4; + const isHeadOdd = (head & 1) === 1; + if (isHeadOdd !== isYOdd) + y = Fp2.neg(y); + return { x, y }; + } else if (len === uncompressedLen && head === 4) { + const x = Fp2.fromBytes(tail.subarray(0, Fp2.BYTES)); + const y = Fp2.fromBytes(tail.subarray(Fp2.BYTES, 2 * Fp2.BYTES)); + return { x, y }; + } else { + throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`); + } + } + }); + const numToNByteStr = (num) => bytesToHex2(numberToBytesBE(num, CURVE.nByteLength)); + function isBiggerThanHalfOrder(number3) { + const HALF = CURVE_ORDER >> _1n4; + return number3 > HALF; + } + function normalizeS(s) { + return isBiggerThanHalfOrder(s) ? modN2(-s) : s; + } + const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to)); + class Signature { + constructor(r, s, recovery) { + this.r = r; + this.s = s; + this.recovery = recovery; + this.assertValidity(); + } + static fromCompact(hex2) { + const l = CURVE.nByteLength; + hex2 = ensureBytes("compactSignature", hex2, l * 2); + return new Signature(slcNum(hex2, 0, l), slcNum(hex2, l, 2 * l)); + } + static fromDER(hex2) { + const { r, s } = DER.toSig(ensureBytes("DER", hex2)); + return new Signature(r, s); + } + assertValidity() { + if (!isWithinCurveOrder(this.r)) + throw new Error("r must be 0 < r < CURVE.n"); + if (!isWithinCurveOrder(this.s)) + throw new Error("s must be 0 < s < CURVE.n"); + } + addRecoveryBit(recovery) { + return new Signature(this.r, this.s, recovery); + } + recoverPublicKey(msgHash) { + const { r, s, recovery: rec } = this; + const h = bits2int_modN(ensureBytes("msgHash", msgHash)); + if (rec == null || ![0, 1, 2, 3].includes(rec)) + throw new Error("recovery id invalid"); + const radj = rec === 2 || rec === 3 ? r + CURVE.n : r; + if (radj >= Fp2.ORDER) + throw new Error("recovery id 2 or 3 invalid"); + const prefix = (rec & 1) === 0 ? "02" : "03"; + const R = Point2.fromHex(prefix + numToNByteStr(radj)); + const ir = invN(radj); + const u1 = modN2(-h * ir); + const u2 = modN2(s * ir); + const Q = Point2.BASE.multiplyAndAddUnsafe(R, u1, u2); + if (!Q) + throw new Error("point at infinify"); + Q.assertValidity(); + return Q; + } + hasHighS() { + return isBiggerThanHalfOrder(this.s); + } + normalizeS() { + return this.hasHighS() ? new Signature(this.r, modN2(-this.s), this.recovery) : this; + } + toDERRawBytes() { + return hexToBytes2(this.toDERHex()); + } + toDERHex() { + return DER.hexFromSig({ r: this.r, s: this.s }); + } + toCompactRawBytes() { + return hexToBytes2(this.toCompactHex()); + } + toCompactHex() { + return numToNByteStr(this.r) + numToNByteStr(this.s); + } + } + const utils = { + isValidPrivateKey(privateKey) { + try { + normPrivateKeyToScalar(privateKey); + return true; + } catch (error) { + return false; + } + }, + normPrivateKeyToScalar, + randomPrivateKey: () => { + const length = getMinHashLength(CURVE.n); + return mapHashToField(CURVE.randomBytes(length), CURVE.n); + }, + precompute(windowSize = 8, point = Point2.BASE) { + point._setWindowSize(windowSize); + point.multiply(BigInt(3)); + return point; + } + }; + function getPublicKey2(privateKey, isCompressed = true) { + return Point2.fromPrivateKey(privateKey).toRawBytes(isCompressed); + } + function isProbPub(item) { + const arr = item instanceof Uint8Array; + const str = typeof item === "string"; + const len = (arr || str) && item.length; + if (arr) + return len === compressedLen || len === uncompressedLen; + if (str) + return len === 2 * compressedLen || len === 2 * uncompressedLen; + if (item instanceof Point2) + return true; + return false; + } + function getSharedSecret(privateA, publicB, isCompressed = true) { + if (isProbPub(privateA)) + throw new Error("first arg must be private key"); + if (!isProbPub(publicB)) + throw new Error("second arg must be public key"); + const b = Point2.fromHex(publicB); + return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed); + } + const bits2int = CURVE.bits2int || function(bytes3) { + const num = bytesToNumberBE(bytes3); + const delta = bytes3.length * 8 - CURVE.nBitLength; + return delta > 0 ? num >> BigInt(delta) : num; + }; + const bits2int_modN = CURVE.bits2int_modN || function(bytes3) { + return modN2(bits2int(bytes3)); + }; + const ORDER_MASK = bitMask(CURVE.nBitLength); + function int2octets(num) { + if (typeof num !== "bigint") + throw new Error("bigint expected"); + if (!(_0n4 <= num && num < ORDER_MASK)) + throw new Error(`bigint expected < 2^${CURVE.nBitLength}`); + return numberToBytesBE(num, CURVE.nByteLength); + } + function prepSig(msgHash, privateKey, opts = defaultSigOpts) { + if (["recovered", "canonical"].some((k) => k in opts)) + throw new Error("sign() legacy options not supported"); + const { hash: hash3, randomBytes: randomBytes2 } = CURVE; + let { lowS, prehash, extraEntropy: ent } = opts; + if (lowS == null) + lowS = true; + msgHash = ensureBytes("msgHash", msgHash); + if (prehash) + msgHash = ensureBytes("prehashed msgHash", hash3(msgHash)); + const h1int = bits2int_modN(msgHash); + const d = normPrivateKeyToScalar(privateKey); + const seedArgs = [int2octets(d), int2octets(h1int)]; + if (ent != null) { + const e = ent === true ? randomBytes2(Fp2.BYTES) : ent; + seedArgs.push(ensureBytes("extraEntropy", e)); + } + const seed = concatBytes3(...seedArgs); + const m = h1int; + function k2sig(kBytes) { + const k = bits2int(kBytes); + if (!isWithinCurveOrder(k)) + return; + const ik = invN(k); + const q = Point2.BASE.multiply(k).toAffine(); + const r = modN2(q.x); + if (r === _0n4) + return; + const s = modN2(ik * modN2(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 = normalizeS(s); + recovery ^= 1; + } + return new Signature(r, normS, recovery); + } + return { seed, k2sig }; + } + const defaultSigOpts = { lowS: CURVE.lowS, prehash: false }; + const defaultVerOpts = { lowS: CURVE.lowS, prehash: false }; + function sign(msgHash, privKey, opts = defaultSigOpts) { + const { seed, k2sig } = prepSig(msgHash, privKey, opts); + const C = CURVE; + const drbg = createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac); + return drbg(seed, k2sig); + } + Point2.BASE._setWindowSize(8); + function verify(signature, msgHash, publicKey, opts = defaultVerOpts) { + const sg = signature; + msgHash = ensureBytes("msgHash", msgHash); + publicKey = ensureBytes("publicKey", publicKey); + if ("strict" in opts) + throw new Error("options.strict was renamed to lowS"); + const { lowS, prehash } = opts; + let _sig = void 0; + let P; + try { + if (typeof sg === "string" || sg instanceof Uint8Array) { + try { + _sig = Signature.fromDER(sg); + } catch (derError) { + if (!(derError instanceof DER.Err)) + throw derError; + _sig = Signature.fromCompact(sg); + } + } else if (typeof sg === "object" && typeof sg.r === "bigint" && typeof sg.s === "bigint") { + const { r: r2, s: s2 } = sg; + _sig = new Signature(r2, s2); + } else { + throw new Error("PARSE"); + } + P = Point2.fromHex(publicKey); + } catch (error) { + if (error.message === "PARSE") + throw new Error(`signature must be Signature instance, Uint8Array or hex string`); + return false; + } + if (lowS && _sig.hasHighS()) + return false; + if (prehash) + msgHash = CURVE.hash(msgHash); + const { r, s } = _sig; + const h = bits2int_modN(msgHash); + const is = invN(s); + const u1 = modN2(h * is); + const u2 = modN2(r * is); + const R = Point2.BASE.multiplyAndAddUnsafe(P, u1, u2)?.toAffine(); + if (!R) + return false; + const v = modN2(R.x); + return v === r; + } + return { + CURVE, + getPublicKey: getPublicKey2, + getSharedSecret, + sign, + verify, + ProjectivePoint: Point2, + Signature, + utils + }; + } + + // node_modules/@noble/curves/node_modules/@noble/hashes/esm/hmac.js + var HMAC = class extends Hash2 { + constructor(hash3, _key) { + super(); + this.finished = false; + this.destroyed = false; + hash(hash3); + const key = toBytes2(_key); + this.iHash = hash3.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 pad = new Uint8Array(blockLen); + pad.set(key.length > blockLen ? hash3.create().update(key).digest() : key); + for (let i2 = 0; i2 < pad.length; i2++) + pad[i2] ^= 54; + this.iHash.update(pad); + this.oHash = hash3.create(); + for (let i2 = 0; i2 < pad.length; i2++) + pad[i2] ^= 54 ^ 92; + this.oHash.update(pad); + pad.fill(0); + } + update(buf) { + exists(this); + this.iHash.update(buf); + return this; + } + digestInto(out) { + exists(this); + bytes(out, this.outputLen); + 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 || (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; + } + destroy() { + this.destroyed = true; + this.oHash.destroy(); + this.iHash.destroy(); + } + }; + var hmac = (hash3, key, message) => new HMAC(hash3, key).update(message).digest(); + hmac.create = (hash3, key) => new HMAC(hash3, key); + + // node_modules/@noble/curves/esm/_shortw_utils.js + function getHash(hash3) { + return { + hash: hash3, + hmac: (key, ...msgs) => hmac(hash3, key, concatBytes2(...msgs)), + randomBytes + }; + } + function createCurve(curveDef, defHash) { + const create = (hash3) => weierstrass({ ...curveDef, ...getHash(hash3) }); + return Object.freeze({ ...create(defHash), create }); + } + + // node_modules/@noble/curves/esm/secp256k1.js + var secp256k1P = BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"); + var secp256k1N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"); + var _1n5 = BigInt(1); + var _2n4 = BigInt(2); + var divNearest = (a, b) => (a + b / _2n4) / b; + function sqrtMod(y) { + const P = secp256k1P; + 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, _2n4, 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, _2n4, P); + if (!Fp.eql(Fp.sqr(root), y)) + throw new Error("Cannot find square root"); + return root; + } + var Fp = Field(secp256k1P, void 0, void 0, { sqrt: sqrtMod }); + var secp256k1 = createCurve({ + a: BigInt(0), + b: BigInt(7), + Fp, + n: secp256k1N, + Gx: BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"), + Gy: BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"), + h: BigInt(1), + lowS: true, + endo: { + beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"), + splitScalar: (k) => { + const n = secp256k1N; + const a1 = BigInt("0x3086d221a7d46bcde86c90e49284eb15"); + const b1 = -_1n5 * BigInt("0xe4437ed6010e88286f547fa90abfe4c3"); + const a2 = BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"); + const b2 = a1; + const POW_2_128 = BigInt("0x100000000000000000000000000000000"); + const c1 = divNearest(b2 * k, n); + const c2 = divNearest(-b1 * k, n); + let k1 = mod(k - c1 * a1 - c2 * a2, n); + let k2 = mod(-c1 * b1 - c2 * b2, n); + const k1neg = k1 > POW_2_128; + const k2neg = k2 > POW_2_128; + if (k1neg) + k1 = n - k1; + if (k2neg) + k2 = n - k2; + if (k1 > POW_2_128 || k2 > POW_2_128) { + throw new Error("splitScalar: Endomorphism failed, k=" + k); + } + return { k1neg, k1, k2neg, k2 }; + } + } + }, sha256); + var _0n5 = BigInt(0); + var fe = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1P; + var ge = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1N; + var TAGGED_HASH_PREFIXES = {}; + function taggedHash(tag, ...messages) { + let tagP = TAGGED_HASH_PREFIXES[tag]; + if (tagP === void 0) { + const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0))); + tagP = concatBytes3(tagH, tagH); + TAGGED_HASH_PREFIXES[tag] = tagP; + } + return sha256(concatBytes3(tagP, ...messages)); + } + var pointToBytes = (point) => point.toRawBytes(true).slice(1); + var numTo32b = (n) => numberToBytesBE(n, 32); + var modP = (x) => mod(x, secp256k1P); + var modN = (x) => mod(x, secp256k1N); + var Point = secp256k1.ProjectivePoint; + var GmulAdd = (Q, a, b) => Point.BASE.multiplyAndAddUnsafe(Q, a, b); + function schnorrGetExtPubKey(priv) { + let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); + let p = Point.fromPrivateKey(d_); + const scalar = p.hasEvenY() ? d_ : modN(-d_); + return { scalar, bytes: pointToBytes(p) }; + } + function lift_x(x) { + if (!fe(x)) + throw new Error("bad x: need 0 < x < p"); + const xx = modP(x * x); + const c = modP(xx * x + BigInt(7)); + let y = sqrtMod(c); + if (y % _2n4 !== _0n5) + y = modP(-y); + const p = new Point(x, y, _1n5); + p.assertValidity(); + return p; + } + function challenge(...args) { + return modN(bytesToNumberBE(taggedHash("BIP0340/challenge", ...args))); + } + function schnorrGetPublicKey(privateKey) { + return schnorrGetExtPubKey(privateKey).bytes; + } + function schnorrSign(message, privateKey, auxRand = randomBytes(32)) { + const m = ensureBytes("message", message); + const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey); + const a = ensureBytes("auxRand", auxRand, 32); + const t = numTo32b(d ^ bytesToNumberBE(taggedHash("BIP0340/aux", a))); + const rand = taggedHash("BIP0340/nonce", t, px, m); + const k_ = modN(bytesToNumberBE(rand)); + if (k_ === _0n5) + throw new Error("sign failed: k is zero"); + const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); + const e = challenge(rx, px, m); + const sig = new Uint8Array(64); + sig.set(rx, 0); + sig.set(numTo32b(modN(k + e * d)), 32); + if (!schnorrVerify(sig, m, px)) + throw new Error("sign: Invalid signature produced"); + return sig; + } + function schnorrVerify(signature, message, publicKey) { + const sig = ensureBytes("signature", signature, 64); + const m = ensureBytes("message", message); + const pub = ensureBytes("publicKey", publicKey, 32); + try { + const P = lift_x(bytesToNumberBE(pub)); + const r = bytesToNumberBE(sig.subarray(0, 32)); + if (!fe(r)) + return false; + const s = bytesToNumberBE(sig.subarray(32, 64)); + if (!ge(s)) + return false; + const e = challenge(numTo32b(r), pointToBytes(P), m); + const R = GmulAdd(P, s, modN(-e)); + if (!R || !R.hasEvenY() || R.toAffine().x !== r) + return false; + return true; + } catch (error) { + return false; + } + } + var schnorr = /* @__PURE__ */ (() => ({ + getPublicKey: schnorrGetPublicKey, + sign: schnorrSign, + verify: schnorrVerify, + utils: { + randomPrivateKey: secp256k1.utils.randomPrivateKey, + lift_x, + pointToBytes, + numberToBytesBE, + bytesToNumberBE, + taggedHash, + mod + } + }))(); + + // node_modules/@noble/hashes/esm/_assert.js + function number2(n) { + if (!Number.isSafeInteger(n) || n < 0) + throw new Error(`Wrong positive integer: ${n}`); + } + function bool(b) { + if (typeof b !== "boolean") + throw new Error(`Expected boolean, not ${b}`); + } + function bytes2(b, ...lengths) { + if (!(b instanceof Uint8Array)) + throw new Error("Expected Uint8Array"); + if (lengths.length > 0 && !lengths.includes(b.length)) + throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`); + } + function hash2(hash3) { + if (typeof hash3 !== "function" || typeof hash3.create !== "function") + throw new Error("Hash should be wrapped by utils.wrapConstructor"); + number2(hash3.outputLen); + number2(hash3.blockLen); + } + function exists2(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 output2(out, instance) { + bytes2(out); + const min = instance.outputLen; + if (out.length < min) { + throw new Error(`digestInto() expects output buffer of length at least ${min}`); + } + } + var assert = { + number: number2, + bool, + bytes: bytes2, + hash: hash2, + exists: exists2, + output: output2 + }; + var assert_default = assert; + + // node_modules/@noble/hashes/esm/_sha2.js + function setBigUint642(view, byteOffset, value, isLE3) { + if (typeof view.setBigUint64 === "function") + return view.setBigUint64(byteOffset, value, isLE3); + const _32n = BigInt(32); + const _u32_max = BigInt(4294967295); + const wh = Number(value >> _32n & _u32_max); + const wl = Number(value & _u32_max); + const h = isLE3 ? 4 : 0; + const l = isLE3 ? 0 : 4; + view.setUint32(byteOffset + h, wh, isLE3); + view.setUint32(byteOffset + l, wl, isLE3); + } + var SHA22 = class extends Hash { + constructor(blockLen, outputLen, padOffset, isLE3) { + super(); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE3; + this.finished = false; + this.length = 0; + this.pos = 0; + this.destroyed = false; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + } + update(data) { + assert_default.exists(this); + const { view, buffer, blockLen } = this; + data = toBytes(data); + 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) { + assert_default.exists(this); + assert_default.output(out, this); + this.finished = true; + const { buffer, view, blockLen, isLE: isLE3 } = this; + let { pos } = this; + buffer[pos++] = 128; + this.buffer.subarray(pos).fill(0); + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + for (let i2 = pos; i2 < blockLen; i2++) + buffer[i2] = 0; + setBigUint642(view, blockLen - 8, BigInt(this.length * 8), isLE3); + this.process(view, 0); + const oview = createView(out); + const len = this.outputLen; + if (len % 4) + throw new Error("_sha2: outputLen should 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], isLE3); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to || (to = new this.constructor()); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.length = length; + to.pos = pos; + to.finished = finished; + to.destroyed = destroyed; + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + }; + + // node_modules/@noble/hashes/esm/sha256.js + var Chi2 = (a, b, c) => a & b ^ ~a & c; + var Maj2 = (a, b, c) => a & b ^ a & c ^ b & c; + var SHA256_K2 = new Uint32Array([ + 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 IV2 = new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 + ]); + var SHA256_W2 = new Uint32Array(64); + var SHA2562 = class extends SHA22 { + constructor() { + super(64, 32, 8, false); + this.A = IV2[0] | 0; + this.B = IV2[1] | 0; + this.C = IV2[2] | 0; + this.D = IV2[3] | 0; + this.E = IV2[4] | 0; + this.F = IV2[5] | 0; + this.G = IV2[6] | 0; + this.H = IV2[7] | 0; + } + 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_W2[i2] = view.getUint32(offset, false); + for (let i2 = 16; i2 < 64; i2++) { + const W15 = SHA256_W2[i2 - 15]; + const W2 = SHA256_W2[i2 - 2]; + const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3; + const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10; + SHA256_W2[i2] = s1 + SHA256_W2[i2 - 7] + s0 + SHA256_W2[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 + Chi2(E, F, G) + SHA256_K2[i2] + SHA256_W2[i2] | 0; + const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); + const T2 = sigma0 + Maj2(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() { + SHA256_W2.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0); + this.buffer.fill(0); + } + }; + var SHA224 = class extends SHA2562 { + constructor() { + super(); + this.A = 3238371032 | 0; + this.B = 914150663 | 0; + this.C = 812702999 | 0; + this.D = 4144912697 | 0; + this.E = 4290775857 | 0; + this.F = 1750603025 | 0; + this.G = 1694076839 | 0; + this.H = 3204075428 | 0; + this.outputLen = 28; + } + }; + var sha2562 = wrapConstructor(() => new SHA2562()); + var sha224 = wrapConstructor(() => new SHA224()); + + // node_modules/nostr-tools/lib/esm/pool.js + 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] === "object") + return false; + } + } + return true; + } + var utf8Decoder2 = new TextDecoder("utf-8"); + var utf8Encoder2 = new TextEncoder(); + function normalizeURL(url) { + if (url.indexOf("://") === -1) + url = "wss://" + url; + let p = new URL(url); + 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(); + } + var QueueNode = class { + value; + next = null; + prev = null; + constructor(message) { + this.value = message; + } + }; + var Queue = class { + first; + last; + constructor() { + this.first = null; + this.last = null; + } + enqueue(value) { + const newNode = new QueueNode(value); + if (!this.last) { + this.first = newNode; + this.last = newNode; + } else if (this.last === this.first) { + this.last = newNode; + this.last.prev = this.first; + this.first.next = newNode; + } else { + newNode.prev = this.last; + this.last.next = newNode; + this.last = newNode; + } + return true; + } + dequeue() { + if (!this.first) + return null; + if (this.first === this.last) { + const target2 = this.first; + this.first = null; + this.last = null; + return target2.value; + } + const target = this.first; + this.first = target.next; + return target.value; + } + }; + var JS = class { + generateSecretKey() { + return schnorr.utils.randomPrivateKey(); + } + 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(getEventHash(event), secretKey)); + event[verifiedSymbol] = true; + return event; + } + verifyEvent(event) { + if (typeof event[verifiedSymbol] === "boolean") + return event[verifiedSymbol]; + const hash3 = getEventHash(event); + if (hash3 !== event.id) { + event[verifiedSymbol] = false; + return false; + } + try { + const valid = schnorr.verify(event.sig, hash3, 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 = sha2562(utf8Encoder2.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; + var ClientAuth = 22242; + 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 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 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 makeAuthEvent(relayURL, challenge2) { + return { + kind: ClientAuth, + created_at: Math.floor(Date.now() / 1e3), + tags: [ + ["relay", relayURL], + ["challenge", challenge2] + ], + content: "" + }; + } + async function yieldThread() { + return new Promise((resolve) => { + const ch = new MessageChannel(); + const handler = () => { + ch.port1.removeEventListener("message", handler); + resolve(); + }; + ch.port1.addEventListener("message", handler); + ch.port2.postMessage(0); + ch.port1.start(); + }); + } + var alwaysTrue = (t) => { + t[verifiedSymbol] = true; + return true; + }; + var AbstractRelay = class { + url; + _connected = false; + onclose = null; + onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`); + _onauth = null; + baseEoseTimeout = 4400; + connectionTimeout = 4400; + openSubs = /* @__PURE__ */ new Map(); + connectionTimeoutHandle; + connectionPromise; + openCountRequests = /* @__PURE__ */ new Map(); + openEventPublishes = /* @__PURE__ */ new Map(); + ws; + incomingMessageQueue = new Queue(); + queueRunning = false; + challenge; + serial = 0; + verifyEvent; + _WebSocket; + constructor(url, opts) { + this.url = normalizeURL(url); + this.verifyEvent = opts.verifyEvent; + this._WebSocket = opts.websocketImplementation || WebSocket; + } + static async connect(url, opts) { + const relay = new AbstractRelay(url, opts); + await relay.connect(); + 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 connect() { + if (this.connectionPromise) + return this.connectionPromise; + this.challenge = void 0; + this.connectionPromise = new Promise((resolve, reject) => { + this.connectionTimeoutHandle = setTimeout(() => { + reject("connection timed out"); + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection timed out"); + }, this.connectionTimeout); + try { + this.ws = new this._WebSocket(this.url); + } catch (err) { + reject(err); + return; + } + this.ws.onopen = () => { + clearTimeout(this.connectionTimeoutHandle); + this._connected = true; + resolve(); + }; + this.ws.onerror = (ev) => { + reject(ev.message || "websocket error"); + if (this._connected) { + this._connected = false; + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection errored"); + } + }; + this.ws.onclose = async () => { + if (this._connected) { + this._connected = false; + this.connectionPromise = void 0; + this.onclose?.(); + this.closeAllSubscriptions("relay connection closed"); + } + }; + this.ws.onmessage = this._onmessage.bind(this); + }); + return this.connectionPromise; + } + async runQueue() { + this.queueRunning = true; + while (true) { + if (false === this.handleNext()) { + break; + } + await yieldThread(); + } + this.queueRunning = false; + } + handleNext() { + const json = this.incomingMessageQueue.dequeue(); + if (!json) { + return false; + } + 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); + } + 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 (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]; + this._onauth?.(data[1]); + return; + } + } + } catch (err) { + return; + } + } + async send(message) { + if (!this.connectionPromise) + throw new Error("sending on closed connection"); + this.connectionPromise.then(() => { + this.ws?.send(message); + }); + } + async auth(signAuthEvent) { + if (!this.challenge) + throw new Error("can't perform auth, no challenge was received"); + const evt = await signAuthEvent(makeAuthEvent(this.url, this.challenge)); + const ret = new Promise((resolve, reject) => { + this.openEventPublishes.set(evt.id, { resolve, reject }); + }); + this.send('["AUTH",' + JSON.stringify(evt) + "]"); + return ret; + } + async publish(event) { + const ret = new Promise((resolve, reject) => { + this.openEventPublishes.set(event.id, { resolve, reject }); + }); + this.send('["EVENT",' + JSON.stringify(event) + "]"); + 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) { + const subscription = this.prepareSubscription(filters, params); + subscription.fire(); + return subscription; + } + prepareSubscription(filters, params) { + this.serial++; + const id = params.id || "sub:" + this.serial; + const subscription = new Subscription(this, id, filters, params); + this.openSubs.set(id, subscription); + return subscription; + } + close() { + this.closeAllSubscriptions("relay connection closed by us"); + this._connected = false; + this.ws?.close(); + } + _onmessage(ev) { + this.incomingMessageQueue.enqueue(ev.data); + if (!this.queueRunning) { + this.runQueue(); + } + } + }; + var Subscription = class { + relay; + id; + closed = false; + eosed = false; + filters; + alreadyHaveEvent; + receivedEvent; + onevent; + oneose; + onclose; + eoseTimeout; + eoseTimeoutHandle; + constructor(relay, id, filters, params) { + 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) { + this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]"); + this.closed = true; + } + this.relay.openSubs.delete(this.id); + this.onclose?.(reason); + } + }; + var AbstractSimplePool = class { + relays = /* @__PURE__ */ new Map(); + seenOn = /* @__PURE__ */ new Map(); + trackRelays = false; + verifyEvent; + trustedRelayURLs = /* @__PURE__ */ new Set(); + _WebSocket; + constructor(opts) { + this.verifyEvent = opts.verifyEvent; + this._WebSocket = opts.websocketImplementation; + } + 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 + }); + if (params?.connectionTimeout) + relay.connectionTimeout = params.connectionTimeout; + this.relays.set(url, relay); + } + await relay.connect(); + return relay; + } + close(relays) { + relays.map(normalizeURL).forEach((url) => { + this.relays.get(url)?.close(); + }); + } + subscribeMany(relays, filters, params) { + return this.subscribeManyMap(Object.fromEntries(relays.map((url) => [url, filters])), params); + } + subscribeManyMap(requests, params) { + 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 relaysLength = Object.keys(requests).length; + const eosesReceived = []; + let handleEose = (i2) => { + eosesReceived[i2] = true; + if (eosesReceived.filter((a) => a).length === relaysLength) { + params.oneose?.(); + handleEose = () => { + }; + } + }; + const closesReceived = []; + let handleClose = (i2, reason) => { + handleEose(i2); + closesReceived[i2] = reason; + if (closesReceived.filter((a) => a).length === relaysLength) { + 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( + Object.entries(requests).map(async (req, i2, arr) => { + if (arr.indexOf(req) !== i2) { + handleClose(i2, "duplicate url"); + return; + } + let [url, filters] = req; + url = normalizeURL(url); + let relay; + try { + relay = await this.ensureRelay(url, { + connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : void 0 + }); + } catch (err) { + handleClose(i2, err?.message || String(err)); + return; + } + let subscription = relay.subscribe(filters, { + ...params, + oneose: () => handleEose(i2), + onclose: (reason) => handleClose(i2, reason), + alreadyHaveEvent: localAlreadyHaveEventHandler, + eoseTimeout: params.maxWait + }); + subs.push(subscription); + }) + ); + return { + async close() { + await allOpened; + subs.forEach((sub) => { + sub.close(); + }); + } + }; + } + subscribeManyEose(relays, filters, params) { + const subcloser = this.subscribeMany(relays, filters, { + ...params, + oneose() { + subcloser.close(); + } + }); + return subcloser; + } + async querySync(relays, filter, params) { + return new Promise(async (resolve) => { + const events = []; + this.subscribeManyEose(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) { + return relays.map(normalizeURL).map(async (url, i2, arr) => { + if (arr.indexOf(url) !== i2) { + return Promise.reject("duplicate url"); + } + let r = await this.ensureRelay(url); + return r.publish(event); + }); + } + }; + var _WebSocket; + try { + _WebSocket = WebSocket; + } catch { + } + var SimplePool = class extends AbstractSimplePool { + constructor() { + super({ verifyEvent, websocketImplementation: _WebSocket }); + } + }; + + // node_modules/nostr-tools/lib/esm/nip05.js + var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/; + var _fetch; + try { + _fetch = fetch; + } catch { + } + 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 (await _fetch(url, { redirect: "error" })).json(); + let pubkey = res.names[name]; + return pubkey ? { pubkey, relays: res.relays?.[pubkey] } : null; + } catch (_e) { + return null; + } + } + + // metadata.ts + var import_lru_cache = __toESM(require_lru_cache(), 1); + var pool = window.nostrSharedPool || new SimplePool(); + var metadataCache = window.nostrMetadataCache || new import_lru_cache.default(2e3); + function fetchMetadata(pubkey, hints) { + let metadata = metadataCache.get(pubkey); + if (metadata) + return metadata; + const relays = ["wss://purplepag.es", "wss://user.kindpag.es", "wss://relay.nos.social"]; + relays.push(...hints); + let promise = new Promise( + (resolve, reject) => pool.subscribeManyEose( + relays, + [ + { + kinds: [0], + authors: [pubkey] + } + ], + { + onevent(evt) { + try { + resolve(JSON.parse(evt.content)); + } catch (err) { + } + }, + onclose: reject + } + ) + ); + metadataCache.set(pubkey, promise); + return promise; + } + async function inputToPubkey(input) { + try { + const { type, data } = decode(input); + if (type === "nprofile") { + return [data.pubkey, data.relays || []]; + } else if (type === "npub") { + return [data, []]; + } + } catch (err) { + if (input.match(/[0-9a-f]{64}/)) { + return [input, []]; + } else if (input.match(".")) { + let res = await queryProfile(input); + if (!res) + return [void 0]; + return [res.pubkey, res.relays || []]; + } + } + return [void 0]; + } + + // nostr-picture.ts + var import_debounce = __toESM(require_debounce(), 1); + + // utils.ts + var transparentPixel = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="; + function handleImageError(ev) { + const el = ev.target; + console.log("error loading image", ev); + if (el.src !== transparentPixel) { + el.src = transparentPixel; + } + } + + // nostr-picture.ts + var NostrPicture = class extends HTMLElement { + img; + constructor() { + super(); + this.img = document.createElement("img"); + this.img.setAttribute("part", "img"); + this.img.onerror = handleImageError; + this.attachShadow({ mode: "open" }); + const { shadowRoot } = this; + shadowRoot.appendChild(this.img); + } + connectedCallback() { + this.style.display = "inline-block"; + this.style.width = "fit-content"; + this.style.height = "fit-content"; + this.set(); + } + attributeChangedCallback(name, _, value) { + if (name === "pubkey") + this.set(); + else if (name === "width" || name === "height") + this.img.setAttribute(name, value); + } + set = (0, import_debounce.default)(async () => { + let input = this.getAttribute("pubkey"); + if (input) { + let [pubkey, hints] = await inputToPubkey(input); + if (pubkey) { + let metadata = await fetchMetadata(pubkey, hints || []); + this.img.src = metadata.picture || transparentPixel; + let name = metadata.name || metadata.display_name || npubEncode(pubkey); + this.img.alt = `picture for "${name}"`; + } + } + }, 200); + }; + __publicField(NostrPicture, "observedAttributes", ["pubkey", "width", "height"]); + window.customElements.define("nostr-picture", NostrPicture); +})(); diff --git a/public/logo.jpg b/public/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4941c28a16c88f78582a7b5d057fad4285f83680 GIT binary patch literal 45294 zcmb5V1#le65;izu*&>TAw%B53vX~`{8Ar^_U|Y=0%#y{-%rIhRW@h%y?%TKb$BVnT zxSE;np6afzzM{;ms_Z|De>MT1q{Jk}01yxm0DbTW@Mi@e41k7$`s)h~1q}lY4FmfT z4i+4cK754#h=TO#6ABUvGAjCK3{*61G-MP^d`xT{96UU{PZ$J51h_<>aq)2f0)c>r zfq{jAMTCPx#6?9x#r^*s{`3G);UU_g08kJl07z5_C{&0)eE@s_1OO81FS`E*SU6}H zcqquf?&5;u!FT_?1-^iShJ=BI__GW^1jj>ug8BpiKy-HfpHKXMUNepPd&=@F6=)Px zXDs)OCrxXGU$=d@rf%lq4zZ zXUeU{;f|NZ9~7s8)k#y?z1LB*7ZLxMAw8;tL!qc1-<(_WJ6xW0#u&8n2G^-oecX6( zfnExkRch0s^tC0oCpO?+0t58}wrLubDF;BW($&pNWp^h{Ktue;_^?Hl&qIScijC0 zdrc);S(WPm;?pk=VzMZhBAhUNc{1+uy76|q!S9LxelNy9?o&7xA?em`h``PGdeNui@{z?g^of-)&h692{O6(uE;=XNh+}@=#fjX8lE4wm zip+k55h!m%w*9j!-Q54fbh zvsL|s%kfZ3edcK$Pu!y~Ehn0lQ=e7alSdAoapEB12=@>!EPH%jn2RLB$uw_hU{zeK zNcE~Te~{Vx(k-BG5>;TwSlVCsJh3V?SNaJHp#;^5=XO5heJBIEaoStHPOy5`Zz_V^b7 zU|V$~RA*^+HHf|scoSeIU%+ZX!dTrug7*3M8KRiBx7gpsYfH9C?AwbIMfk&M2O0Qz z#tBu`$tg~`C;$Ll6xA&@|1Adr!MKj>4t-0txwjE!@d^7s5PY;N0&03m^YO^5EitA{ zXFL6@HO0M}x?CU_F?z)^yRUm)jpU?p4h16(v4iH84o*gqq3zC>0i0d`06=M}E{)Gs zP-hXWm3L$>jpKj|V5Eu3-9eynHnu<{AZImoXfenw%J(YCM9juE%nTfq^w5}`EU9D? z9M8ZWO*HBvKqpwIF827kic}e;zHIcN?liXCe;St(h;g5(& za3bLJqSyFiunU?*-ndyi!%HvKfi3!5aYf_-VeDyKUNf-dXaLvaZ+iSFb(H%9j{c;* zvro#RWu`83b43I5gN-3I>3sjthqTN+Y&XK$Ny(kF)-5r^R`NQta`4Q*YcxJM5VCH& z$)dGX5u)|-(}3I4GjkjtFu#i%)uGC2Mg2z(FwwZ*WH=U$6N%f?2bT}eOW@x`Ef`*R zYB=n#55OrpY=}z6XFJ}43%KiXM58%jZ?Zl+4@$qcxlVN7)Jy({1z4TjdR^=_yytcx z&mNS({QxLpdka^k*410!p}Sg~;}^EU=GhF7IC5c1&RKB}Yc0Nlh^COgAOa}~14C@A z?r7nB#SHe!dGCl6r?|Gt6?lTdm?A! z>sGmCj!1j^Xwf8lL?x9ESF9Z4t$3qS@2w~9o9*LDp^Dibl~u%E%y-CtZl`~j)Ro8? z;CXp$BzuO6i9+U3i5XjCnNa+$y1=;<+uP#4llP^I%?_;nL{0fEvZVPNRm+U^3g#AC z;sd6T`L`QTqS|dMY!?<)U1dGfmXbYj{5Jj~^-n;E9j~DEk=Dl80Y_Li2xK;M#YBPS zc_|5B*uaUg^PA35Lv@1v&D~&9?YZTV1kBgs?pZwzw#HM=y9gzwV8{61=oclOF9*%5 z-TrLGr<(&gTBlyc4fFK*eeKOBvRVkoq~CpH6MBkLUX08QscM#wSGa2C3R;uxD^%Z? z5x-Uhb|;_Y4C97wk}{i#Jbh0SkPAGln7X10=N>QsGX9q*0J??Oh6;7SQkdwksQts+ z^AC%smBEQK9P*lRHjO-`jKlX{9sWv2p0c?mdWW>u^v~|MQc99CSoi$iTHe}2fAM^GE8<}Brn+hlHkbB2jsQotmIj>@_ufbo zzr}r}Xc@byPN#n>s+$5%dvusx1rhp9Pmkg(<4PzFc*>xVr}r|*dyf-}&$Q2(9T#l1 zR0eVH-tJp_aj{K*FJ)Gi^fI|^>e2r37x(+>>>j+yW*o1zFL_{Fh{@X+%<9PIfaj>p z)YFX0`Ke+IHz2ElBK2z)U1aNtIlX3luRStb%l3v^PgOH}y<7u=5Y%@!-Bk1JIb*$~ zt-9BTjbRLiULyLZ4eI@qt-}`jt{N)Q5ljB64K3zIt{42(vxm9M#R0}01^1?z#e{#ipOgZWeyi{R80q zjWjkWnpKu3Xs71BUBu~`tzkv?#xuEtoht)}10nY>m5jB>1 z+x-JbbICnvpfK5&2TJ}DAU^sLv^Q*z1X?MtxMlnDO!ne!Ygv6)P%J#xQHOL>TzO0_ zK8gn-ys2JtQs1dB!{*mb90>jP3}-4JAj=5k!D*>TOg1v3RxS4QwsFnUthxpk%#x3u z9BkMpwLtGU!(v*TtS$OtbN5~mbWVxoUr*`vFHcf&d%!Y_RRvm*01)u zE9hYMhv~4hoU{G`DE5%FP|OnNn9TQTLE8x5=U}tEsH10`b(kNf2C4DuFkU|FfBgZL zo;M~AVPn!^r)03GY0Yjw=Gp3nDmeJhP{7Qr zA8%-q-0z!Rk6%v?uPmkL?>QD$bdI@OI;p8{jZRKFx~hL~<+>%H8zDfTP|<6@EhP|W zuAT&EW*50ouAsqwZ1QZnwF1-5)*#owA+#KUQ>S*-SUctByC z?*iM}h!#@!n&ZXw?><$RU;auBA3;9jOuyczcaOiOnP6T&_U3fJ=B%3Ajs&-Q;!=C7 z9CUCJy#Pz-rReIrm%fRqH=mW$9NB2^eb2&MNU08NX+-u&77T^qo0Uys)=bb|DDL!$ z6xaT%djAUWyqP_g4JYM`=L}iA9VWrb;s1&M&k=57GLQGdWyB-M*^p#_;VbpvD3@C^ zLEuPFsg1{bxPpI%gGB!*L~U`u(25FOf++apH5upOX$vyiVpPTCJPB_`g^Z%T0xDkb?VTM3d>pZoUG z6Prk{cA_Sdj8}x{>9CH+VJZBk2RvS+Pe#gI9?GG-jx0SwW9qb)*9V-+juC8b8?6mWnpTlR+x z^!)Yfc*yu~|IOk5J{#T~i0$aaCFJ8ZQA&E|8MUP`&n_IoxKqw`kEe}NlDe8WMTt7q zmo@3g<18;Ood{UH{~P=Nxbl-z^aQ0M zS4Y@b-K2ub?i&Q4pEBpmy{IL1=Gtc$!lY#R^n1JhNsv!79+KVSIa8{YyodTUC7hoB ze;@$>MBte=!zTa)G$aHBJoxyZ2{#lZc&PvY@d+Ij4FmHFau%jx>>EAFZ%cK-MV zvF?`m&n3p|$f*nJ++$`}trQ@E%Ti6TB-KKsht}Vog7#+Z4KCPz+dcec{H&Cs^O8~J z1cRnW;TrUULr4EfHyoYUo!I?Aew`?P7u}16=D?|*#sW!nu`b1GPy=Qb!{V2yhobwz z&z#E@&3~`7mYJ2cg*MrGSGQ%Wo!6rx}f)JT4*OjD`jO8a>Y1dI9P+MDtt*rhA^opE0NSFsR?7b7 z{gD^qEd<)iUQJi>%?Zrv5EC6Am=g|dZX(ffwc)v-eJ5}A@DJQ#Z*SPB56Ol~^;UKl zAiv+k3~)01m!wB!ewjoD0@E=#7v5yxzKG~qZl!pO&h-?h=)9f zHo5pgERi!7F1<_{-L$bP#~?r^L@gtWILr2tjPbXO#|}CED$Ym-O@TDV=jbJTxv+PM zUE;2EIn=vGA)m|$;CGQY5>gal@hJBoD0b75Q_pnSs+{_pLu+wt%5~Q){=c%U`19}t{|7uBW_@}9+!npdR`8D+S zbJ8zslAGoccjd}?^{J%;mIAn83%N4hIQXaAXy*1}>;vySf%zwF+hP@S`>QHOP=SVf zog~y<5+Nuoz$C%<=I;y+@>51ca;8-M7veYVE{AzX*prMHONthIzuz0yS4xTcP(P_> z=_Gq|rTa%=v8>l(*zj2dB;jV9u+5l@b$2^tg^`shKHy=8Y6!?Me&1AL z3iasDkdA8ev^(L5xY#3?xHm1C~x z_!}G`&^#F77n`QGl2dWb6mxGi2RDL;44n$x(){s@!!aA_m4?@1wCS`)V?*$$@|t>oWe!??8M{i$HEExHEu&x(pJAN z<7&uzIH@{*aUJKaBZe@(w~P$RlQLQ^2BVqvYzr+mjE7l+Yr#dNNjQE(&i`vzpouE# zAAq)qncp^&w?w$+Ei0-g6@T^@(qDpIBrJNmDu=?`5PXYX85}~C2mPX0%GYc#d5Dl4 zdPNUI$D@rYL|Ds=zHGC%o-+21Vpa3QkcJ0jl9^^NY}7C6Ay34c))zq$Hb~MDYcSJ% zX*3|VFp#Ci%J)Z?B|8oWf$j2-gm1y2N4qX_*&1-ji}cak`F%}N8f z61eljQJ*<{IA-^X@CSI!4?hPRvzB%`#@r=ZwWk4-=tK%iEQ;frsjhW8ZTivJuhBmm z68M~a5N9fltYvkJ9b-hMUcyg69{wz|`f5{sR-di-E;|;(SvKf~g|9BVkbEzM#zpfx zEc%C^deSlQ^RcJ`TQ=iuOdQZOcJKlnqyKX}IqseHkfNM*??t~6gohFl!K$ChhnU9b zWW}q=7H<1rB&7; za?x2HgG_s%hxQ9+cT7HD-{o`F<7@`D0EE;uTB)*4$LisTDNdGFjAvzSvkq zpsP*r-GCaA8x=o(RM|$L@d?ZQ`Y20O@9JRr`Thy2BY)!)khJ0H${v{h^OLc`-R2EWC4%r_HTcBcv8Synr7$+*(T;1urhl#N+uCa5vjte zr`yDT;o*!Ghn=yr*_}bRH*Wh&3-rh0oa`j>P4ZDG1{U*h1gokCO{a{w^Gs#-B;+4^ z*ei-We{IT>%4EkWGxToF{sUNw-*z?PQ(f#>GxqTkwS9Sx)D0$D(rp8wN@|l;6lhAZ zT`JybCnj6M68^7#)p02eT&I3U28Fxj1An5m>nl9QCW*kW>od4{f`*GIx0+cl5OS z%LPET=Bp>=5`)IN268d|Ip-O}vx>~EpC`#2ovif2hF=7c6jhzhoJrbyyKu(+JhX2&5H;@+cG4>-?T;ts*HSi{;Iuw`6F8X_Wn0% z9xOIWaU}^8TC~$(n#!EQyy~E)S8o%p7k$Y&6qL^`JbQxtQzWFQSPK+s)@4O(l5#(< z4|N{g6lXgXmFiFJ}*JB{900TV5HhUF=Xwdf6=LxsvXKa zg}H<0SboOi7dx9qlg&}RtyplXz!2eADv1s!W8XF>n(e%48Bq(OIjdF!polc{tfPU* zWXR%rO&(T`=UeUUE0O%lhSA~VT*?S&J^JSIAS(8}3ptLQyxFUZW08dSLw3?_1nG3h4L_HkBi)OF^o=wctb-5LYSxVlA`RYpsH=bvAmO4$G3xVD9Mj?KMt?S5%bcPmJ`U?&nGaN=C*8a_Y z>RM?TTXbk5JyIR)mLl9i$gfLi%z+%9r#+Ij$XFn-h8eD?N)on3GLNROCpn_hz|wi) z$8QzyiwNhpy_UZ!y*Cn(+~N`q64r9e*JamPkmM-us8yET@A?qv|q zRNdkN}t6QoMAa?+}2o>n8$(4*a5Mh+UkObj70 zAlFUf!7@fBc(QXgC(%DDoEY5xnXx?Mb+c&l*cyA6ySyvupBhb1TT1^H;~&s1IFtmV z7_Iv;u?&+h*3S8GNcan}mjrUPD)Zvg7waC=`(_-j9^)cWs*vtly`iyce zDB@Yms9v(UO>XXJ1hG|2*bH3C0=<8TwK`;x#7vOH^r_}A{4C;Dg(+M_`h=I?X3-fn5JxV@eRrw*?2)Dt&ub?1mu)U!k-q^8}o5mk&n?niVW z5gYO!fO}KWQ4jR5z1rGZGM#D|&=D;D8qi?VI@}5$F~;$#H;*`_&Y0YoNY02v=~qi} z84_p7*ALOnUkOmu`)aAFi-oL!-xSW<+$aEXF|=u!n*F?hOx zECh2C&b4{gHAen32>nXI{anVejerpsq?(&{^8T~XW&&eFqyDvN~`&x zyJTjetA?@RuezH|bp2X`TWcVg(^A&j#ZAW_R=Sc~*grOtX=8G2S1DJYz$r$GeT3yy zXF}wD$m~FLBR7_&_93ONAUG=U;49oWn!%XxTyBg}5p9|Tu=i}u#)+vPZ$kr1dHvFf zRgH~kkAPAM=H~YW>h5X8GZ1BSHslShlSoXe!Bu8S-%kD#Ds-9u3YFYyglUoZ;56)D?b~cezsBA zui{Q!ip-dk5q&Mwu=0k9kra*|?F?H~vuKTXjIu70!1r(0;sa+RhgEak;y31=+eS5& zDBF^eh3a*KYOE&&a-Hsn=QOSTih7N@yQgvmxFtM7?LX_eYH(XN$48VoFzQnG2zH?% zJ^dR)7y?BS@LS$xJzp|)TG78S*1=pIY;q8mRm!+K{t7{czGtSUU1$HIaj;Ct(ZG*3 z?BLi&o(nFgS|O;^Vxyph8`OT≷6c5}omRl#7`fv+wuL4&DGl(0Sc(>Rf#(x`mPp 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 literal 0 HcmV?d00001 diff --git a/public/main.js b/public/main.js index 92ba0ed..719861f 100644 --- a/public/main.js +++ b/public/main.js @@ -1,5 +1,8 @@ import { nip19, SimplePool } from "nostr-tools"; +const relays = ["wss://relay.damus.io", "wss://nos.lol", "wss://nostr.wine"]; +const pool = new SimplePool(); + const seen = new Set(); function addSite(event) { if (seen.has(event.pubkey)) return; @@ -10,8 +13,14 @@ function addSite(event) { const site = template.content.cloneNode(true); const npub = nip19.npubEncode(event.pubkey); - site.querySelector(".pubkey").textContent = npub; - site.querySelector(".link").href = new URL("/", `${location.protocol}//${npub}.${location.host}`).toString(); + site.querySelector("nostr-name").setAttribute("pubkey", event.pubkey); + site.querySelector("nostr-name").textContent = npub.slice(0, 8); + site.querySelector("nostr-picture").setAttribute("pubkey", event.pubkey); + + site + .querySelector(".nsite-link") + ?.setAttribute("href", new URL("/", `${location.protocol}//${npub}.${location.host}`).toString()); + site.querySelector("time").textContent = new Date(event.created_at * 1000).toDateString(); document.getElementById("sites").appendChild(site); } catch (error) { @@ -20,13 +29,7 @@ function addSite(event) { } } -const pool = new SimplePool(); - console.log("Loading sites"); -pool.subscribeMany( - ["wss://relay.damus.io", "wss://nos.lol", "wss://nostr.wine"], - [{ kinds: [34128], "#d": ["/index.html"] }], - { - onevent: addSite, - }, -); +pool.subscribeMany(relays, [{ kinds: [34128], "#d": ["/index.html"] }], { + onevent: addSite, +});