create daemon
This commit is contained in:
796
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-pool.js
generated
vendored
Normal file
796
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-pool.js
generated
vendored
Normal file
@@ -0,0 +1,796 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// abstract-pool.ts
|
||||
var abstract_pool_exports = {};
|
||||
__export(abstract_pool_exports, {
|
||||
AbstractSimplePool: () => AbstractSimplePool
|
||||
});
|
||||
module.exports = __toCommonJS(abstract_pool_exports);
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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;
|
||||
};
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
|
||||
// abstract-pool.ts
|
||||
var AbstractSimplePool = class {
|
||||
relays = /* @__PURE__ */ new Map();
|
||||
seenOn = /* @__PURE__ */ new Map();
|
||||
trackRelays = false;
|
||||
verifyEvent;
|
||||
enablePing;
|
||||
trustedRelayURLs = /* @__PURE__ */ new Set();
|
||||
_WebSocket;
|
||||
constructor(opts) {
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
async ensureRelay(url, params) {
|
||||
url = normalizeURL(url);
|
||||
let relay = this.relays.get(url);
|
||||
if (!relay) {
|
||||
relay = new AbstractRelay(url, {
|
||||
verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,
|
||||
websocketImplementation: this._WebSocket,
|
||||
enablePing: this.enablePing
|
||||
});
|
||||
relay.onclose = () => {
|
||||
this.relays.delete(url);
|
||||
};
|
||||
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();
|
||||
this.relays.delete(url);
|
||||
});
|
||||
}
|
||||
subscribe(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
for (let i = 0; i < relays.length; i++) {
|
||||
const url = normalizeURL(relays[i]);
|
||||
if (!request.find((r) => r.url === url)) {
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMany(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
const uniqUrls = [];
|
||||
for (let i = 0; i < relays.length; i++) {
|
||||
const url = normalizeURL(relays[i]);
|
||||
if (uniqUrls.indexOf(url) === -1) {
|
||||
uniqUrls.push(url);
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMap(requests, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const grouped = /* @__PURE__ */ new Map();
|
||||
for (const req of requests) {
|
||||
const { url, filter } = req;
|
||||
if (!grouped.has(url))
|
||||
grouped.set(url, []);
|
||||
grouped.get(url).push(filter);
|
||||
}
|
||||
const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters }));
|
||||
if (this.trackRelays) {
|
||||
params.receivedEvent = (relay, id) => {
|
||||
let set = this.seenOn.get(id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(id, set);
|
||||
}
|
||||
set.add(relay);
|
||||
};
|
||||
}
|
||||
const _knownIds = /* @__PURE__ */ new Set();
|
||||
const subs = [];
|
||||
const eosesReceived = [];
|
||||
let handleEose = (i) => {
|
||||
if (eosesReceived[i])
|
||||
return;
|
||||
eosesReceived[i] = true;
|
||||
if (eosesReceived.filter((a) => a).length === requests.length) {
|
||||
params.oneose?.();
|
||||
handleEose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const closesReceived = [];
|
||||
let handleClose = (i, reason) => {
|
||||
if (closesReceived[i])
|
||||
return;
|
||||
handleEose(i);
|
||||
closesReceived[i] = reason;
|
||||
if (closesReceived.filter((a) => a).length === requests.length) {
|
||||
params.onclose?.(closesReceived);
|
||||
handleClose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const localAlreadyHaveEventHandler = (id) => {
|
||||
if (params.alreadyHaveEvent?.(id)) {
|
||||
return true;
|
||||
}
|
||||
const have = _knownIds.has(id);
|
||||
_knownIds.add(id);
|
||||
return have;
|
||||
};
|
||||
const allOpened = Promise.all(
|
||||
groupedRequests.map(async ({ url, filters }, i) => {
|
||||
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(i, err?.message || String(err));
|
||||
return;
|
||||
}
|
||||
let subscription = relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i),
|
||||
onclose: (reason) => {
|
||||
if (reason.startsWith("auth-required: ") && params.onauth) {
|
||||
relay.auth(params.onauth).then(() => {
|
||||
relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i),
|
||||
onclose: (reason2) => {
|
||||
handleClose(i, reason2);
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
}).catch((err) => {
|
||||
handleClose(i, `auth was required and attempted, but failed with: ${err}`);
|
||||
});
|
||||
} else {
|
||||
handleClose(i, reason);
|
||||
}
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
subs.push(subscription);
|
||||
})
|
||||
);
|
||||
return {
|
||||
async close(reason) {
|
||||
await allOpened;
|
||||
subs.forEach((sub) => {
|
||||
sub.close(reason);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
subscribeEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribe(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
subscribeManyEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribeMany(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
async querySync(relays, filter, params) {
|
||||
return new Promise(async (resolve) => {
|
||||
const events = [];
|
||||
this.subscribeEose(relays, filter, {
|
||||
...params,
|
||||
onevent(event) {
|
||||
events.push(event);
|
||||
},
|
||||
onclose(_) {
|
||||
resolve(events);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
async get(relays, filter, params) {
|
||||
filter.limit = 1;
|
||||
const events = await this.querySync(relays, filter, params);
|
||||
events.sort((a, b) => b.created_at - a.created_at);
|
||||
return events[0] || null;
|
||||
}
|
||||
publish(relays, event, options) {
|
||||
return relays.map(normalizeURL).map(async (url, i, arr) => {
|
||||
if (arr.indexOf(url) !== i) {
|
||||
return Promise.reject("duplicate url");
|
||||
}
|
||||
let r = await this.ensureRelay(url);
|
||||
return r.publish(event).catch(async (err) => {
|
||||
if (err instanceof Error && err.message.startsWith("auth-required: ") && options?.onauth) {
|
||||
await r.auth(options.onauth);
|
||||
return r.publish(event);
|
||||
}
|
||||
throw err;
|
||||
}).then((reason) => {
|
||||
if (this.trackRelays) {
|
||||
let set = this.seenOn.get(event.id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(event.id, set);
|
||||
}
|
||||
set.add(r);
|
||||
}
|
||||
return reason;
|
||||
});
|
||||
});
|
||||
}
|
||||
listConnectionStatus() {
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
this.relays.forEach((relay, url) => map.set(url, relay.connected));
|
||||
return map;
|
||||
}
|
||||
destroy() {
|
||||
this.relays.forEach((conn) => conn.close());
|
||||
this.relays = /* @__PURE__ */ new Map();
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-pool.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-pool.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
551
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-relay.js
generated
vendored
Normal file
551
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-relay.js
generated
vendored
Normal file
@@ -0,0 +1,551 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// abstract-relay.ts
|
||||
var abstract_relay_exports = {};
|
||||
__export(abstract_relay_exports, {
|
||||
AbstractRelay: () => AbstractRelay,
|
||||
SendingOnClosedConnection: () => SendingOnClosedConnection,
|
||||
Subscription: () => Subscription
|
||||
});
|
||||
module.exports = __toCommonJS(abstract_relay_exports);
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-relay.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/abstract-relay.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
66
thrower_daemon/node_modules/nostr-tools/lib/cjs/fakejson.js
generated
vendored
Normal file
66
thrower_daemon/node_modules/nostr-tools/lib/cjs/fakejson.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// fakejson.ts
|
||||
var fakejson_exports = {};
|
||||
__export(fakejson_exports, {
|
||||
getHex64: () => getHex64,
|
||||
getInt: () => getInt,
|
||||
getSubscriptionId: () => getSubscriptionId,
|
||||
matchEventId: () => matchEventId,
|
||||
matchEventKind: () => matchEventKind,
|
||||
matchEventPubkey: () => matchEventPubkey
|
||||
});
|
||||
module.exports = __toCommonJS(fakejson_exports);
|
||||
function getHex64(json, field) {
|
||||
let len = field.length + 3;
|
||||
let idx = json.indexOf(`"${field}":`) + len;
|
||||
let s = json.slice(idx).indexOf(`"`) + idx + 1;
|
||||
return json.slice(s, s + 64);
|
||||
}
|
||||
function getInt(json, field) {
|
||||
let len = field.length;
|
||||
let idx = json.indexOf(`"${field}":`) + len + 3;
|
||||
let sliced = json.slice(idx);
|
||||
let end = Math.min(sliced.indexOf(","), sliced.indexOf("}"));
|
||||
return parseInt(sliced.slice(0, end), 10);
|
||||
}
|
||||
function getSubscriptionId(json) {
|
||||
let idx = json.slice(0, 22).indexOf(`"EVENT"`);
|
||||
if (idx === -1)
|
||||
return null;
|
||||
let pstart = json.slice(idx + 7 + 1).indexOf(`"`);
|
||||
if (pstart === -1)
|
||||
return null;
|
||||
let start = idx + 7 + 1 + pstart;
|
||||
let pend = json.slice(start + 1, 80).indexOf(`"`);
|
||||
if (pend === -1)
|
||||
return null;
|
||||
let end = start + 1 + pend;
|
||||
return json.slice(start + 1, end);
|
||||
}
|
||||
function matchEventId(json, id) {
|
||||
return id === getHex64(json, "id");
|
||||
}
|
||||
function matchEventPubkey(json, pubkey) {
|
||||
return pubkey === getHex64(json, "pubkey");
|
||||
}
|
||||
function matchEventKind(json, kind) {
|
||||
return kind === getInt(json, "kind");
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/fakejson.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/fakejson.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../fakejson.ts"],
|
||||
"sourcesContent": ["export function getHex64(json: string, field: string): string {\n let len = field.length + 3\n let idx = json.indexOf(`\"${field}\":`) + len\n let s = json.slice(idx).indexOf(`\"`) + idx + 1\n return json.slice(s, s + 64)\n}\n\nexport function getInt(json: string, field: string): number {\n let len = field.length\n let idx = json.indexOf(`\"${field}\":`) + len + 3\n let sliced = json.slice(idx)\n let end = Math.min(sliced.indexOf(','), sliced.indexOf('}'))\n return parseInt(sliced.slice(0, end), 10)\n}\n\nexport function getSubscriptionId(json: string): string | null {\n let idx = json.slice(0, 22).indexOf(`\"EVENT\"`)\n if (idx === -1) return null\n\n let pstart = json.slice(idx + 7 + 1).indexOf(`\"`)\n if (pstart === -1) return null\n let start = idx + 7 + 1 + pstart\n\n let pend = json.slice(start + 1, 80).indexOf(`\"`)\n if (pend === -1) return null\n let end = start + 1 + pend\n\n return json.slice(start + 1, end)\n}\n\nexport function matchEventId(json: string, id: string): boolean {\n return id === getHex64(json, 'id')\n}\n\nexport function matchEventPubkey(json: string, pubkey: string): boolean {\n return pubkey === getHex64(json, 'pubkey')\n}\n\nexport function matchEventKind(json: string, kind: number): boolean {\n return kind === getInt(json, 'kind')\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,SAAS,MAAc,OAAuB;AAC5D,MAAI,MAAM,MAAM,SAAS;AACzB,MAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI;AACxC,MAAI,IAAI,KAAK,MAAM,GAAG,EAAE,QAAQ,GAAG,IAAI,MAAM;AAC7C,SAAO,KAAK,MAAM,GAAG,IAAI,EAAE;AAC7B;AAEO,SAAS,OAAO,MAAc,OAAuB;AAC1D,MAAI,MAAM,MAAM;AAChB,MAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM;AAC9C,MAAI,SAAS,KAAK,MAAM,GAAG;AAC3B,MAAI,MAAM,KAAK,IAAI,OAAO,QAAQ,GAAG,GAAG,OAAO,QAAQ,GAAG,CAAC;AAC3D,SAAO,SAAS,OAAO,MAAM,GAAG,GAAG,GAAG,EAAE;AAC1C;AAEO,SAAS,kBAAkB,MAA6B;AAC7D,MAAI,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,SAAS;AAC7C,MAAI,QAAQ;AAAI,WAAO;AAEvB,MAAI,SAAS,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,QAAQ,GAAG;AAChD,MAAI,WAAW;AAAI,WAAO;AAC1B,MAAI,QAAQ,MAAM,IAAI,IAAI;AAE1B,MAAI,OAAO,KAAK,MAAM,QAAQ,GAAG,EAAE,EAAE,QAAQ,GAAG;AAChD,MAAI,SAAS;AAAI,WAAO;AACxB,MAAI,MAAM,QAAQ,IAAI;AAEtB,SAAO,KAAK,MAAM,QAAQ,GAAG,GAAG;AAClC;AAEO,SAAS,aAAa,MAAc,IAAqB;AAC9D,SAAO,OAAO,SAAS,MAAM,IAAI;AACnC;AAEO,SAAS,iBAAiB,MAAc,QAAyB;AACtE,SAAO,WAAW,SAAS,MAAM,QAAQ;AAC3C;AAEO,SAAS,eAAe,MAAc,MAAuB;AAClE,SAAO,SAAS,OAAO,MAAM,MAAM;AACrC;",
|
||||
"names": []
|
||||
}
|
||||
111
thrower_daemon/node_modules/nostr-tools/lib/cjs/filter.js
generated
vendored
Normal file
111
thrower_daemon/node_modules/nostr-tools/lib/cjs/filter.js
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// filter.ts
|
||||
var filter_exports = {};
|
||||
__export(filter_exports, {
|
||||
getFilterLimit: () => getFilterLimit,
|
||||
matchFilter: () => matchFilter,
|
||||
matchFilters: () => matchFilters,
|
||||
mergeFilters: () => mergeFilters
|
||||
});
|
||||
module.exports = __toCommonJS(filter_exports);
|
||||
|
||||
// kinds.ts
|
||||
function isReplaceableKind(kind) {
|
||||
return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;
|
||||
}
|
||||
function isAddressableKind(kind) {
|
||||
return 3e4 <= kind && kind < 4e4;
|
||||
}
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function mergeFilters(...filters) {
|
||||
let result = {};
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
let filter = filters[i];
|
||||
Object.entries(filter).forEach(([property, values]) => {
|
||||
if (property === "kinds" || property === "ids" || property === "authors" || property[0] === "#") {
|
||||
result[property] = result[property] || [];
|
||||
for (let v = 0; v < values.length; v++) {
|
||||
let value = values[v];
|
||||
if (!result[property].includes(value))
|
||||
result[property].push(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (filter.limit && (!result.limit || filter.limit > result.limit))
|
||||
result.limit = filter.limit;
|
||||
if (filter.until && (!result.until || filter.until > result.until))
|
||||
result.until = filter.until;
|
||||
if (filter.since && (!result.since || filter.since < result.since))
|
||||
result.since = filter.since;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getFilterLimit(filter) {
|
||||
if (filter.ids && !filter.ids.length)
|
||||
return 0;
|
||||
if (filter.kinds && !filter.kinds.length)
|
||||
return 0;
|
||||
if (filter.authors && !filter.authors.length)
|
||||
return 0;
|
||||
for (const [key, value] of Object.entries(filter)) {
|
||||
if (key[0] === "#" && Array.isArray(value) && !value.length)
|
||||
return 0;
|
||||
}
|
||||
return Math.min(
|
||||
Math.max(0, filter.limit ?? Infinity),
|
||||
filter.ids?.length ?? Infinity,
|
||||
filter.authors?.length && filter.kinds?.every((kind) => isReplaceableKind(kind)) ? filter.authors.length * filter.kinds.length : Infinity,
|
||||
filter.authors?.length && filter.kinds?.every((kind) => isAddressableKind(kind)) && filter["#d"]?.length ? filter.authors.length * filter.kinds.length * filter["#d"].length : Infinity
|
||||
);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/filter.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/filter.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2783
thrower_daemon/node_modules/nostr-tools/lib/cjs/index.js
generated
vendored
Normal file
2783
thrower_daemon/node_modules/nostr-tools/lib/cjs/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/index.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
243
thrower_daemon/node_modules/nostr-tools/lib/cjs/kinds.js
generated
vendored
Normal file
243
thrower_daemon/node_modules/nostr-tools/lib/cjs/kinds.js
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// kinds.ts
|
||||
var kinds_exports = {};
|
||||
__export(kinds_exports, {
|
||||
Application: () => Application,
|
||||
BadgeAward: () => BadgeAward,
|
||||
BadgeDefinition: () => BadgeDefinition,
|
||||
BlockedRelaysList: () => BlockedRelaysList,
|
||||
BookmarkList: () => BookmarkList,
|
||||
Bookmarksets: () => Bookmarksets,
|
||||
Calendar: () => Calendar,
|
||||
CalendarEventRSVP: () => CalendarEventRSVP,
|
||||
ChannelCreation: () => ChannelCreation,
|
||||
ChannelHideMessage: () => ChannelHideMessage,
|
||||
ChannelMessage: () => ChannelMessage,
|
||||
ChannelMetadata: () => ChannelMetadata,
|
||||
ChannelMuteUser: () => ChannelMuteUser,
|
||||
ClassifiedListing: () => ClassifiedListing,
|
||||
ClientAuth: () => ClientAuth,
|
||||
CommunitiesList: () => CommunitiesList,
|
||||
CommunityDefinition: () => CommunityDefinition,
|
||||
CommunityPostApproval: () => CommunityPostApproval,
|
||||
Contacts: () => Contacts,
|
||||
CreateOrUpdateProduct: () => CreateOrUpdateProduct,
|
||||
CreateOrUpdateStall: () => CreateOrUpdateStall,
|
||||
Curationsets: () => Curationsets,
|
||||
Date: () => Date,
|
||||
DirectMessageRelaysList: () => DirectMessageRelaysList,
|
||||
DraftClassifiedListing: () => DraftClassifiedListing,
|
||||
DraftLong: () => DraftLong,
|
||||
Emojisets: () => Emojisets,
|
||||
EncryptedDirectMessage: () => EncryptedDirectMessage,
|
||||
EventDeletion: () => EventDeletion,
|
||||
FileMetadata: () => FileMetadata,
|
||||
FileServerPreference: () => FileServerPreference,
|
||||
Followsets: () => Followsets,
|
||||
GenericRepost: () => GenericRepost,
|
||||
Genericlists: () => Genericlists,
|
||||
GiftWrap: () => GiftWrap,
|
||||
HTTPAuth: () => HTTPAuth,
|
||||
Handlerinformation: () => Handlerinformation,
|
||||
Handlerrecommendation: () => Handlerrecommendation,
|
||||
Highlights: () => Highlights,
|
||||
InterestsList: () => InterestsList,
|
||||
Interestsets: () => Interestsets,
|
||||
JobFeedback: () => JobFeedback,
|
||||
JobRequest: () => JobRequest,
|
||||
JobResult: () => JobResult,
|
||||
Label: () => Label,
|
||||
LightningPubRPC: () => LightningPubRPC,
|
||||
LiveChatMessage: () => LiveChatMessage,
|
||||
LiveEvent: () => LiveEvent,
|
||||
LongFormArticle: () => LongFormArticle,
|
||||
Metadata: () => Metadata,
|
||||
Mutelist: () => Mutelist,
|
||||
NWCWalletInfo: () => NWCWalletInfo,
|
||||
NWCWalletRequest: () => NWCWalletRequest,
|
||||
NWCWalletResponse: () => NWCWalletResponse,
|
||||
NostrConnect: () => NostrConnect,
|
||||
OpenTimestamps: () => OpenTimestamps,
|
||||
Pinlist: () => Pinlist,
|
||||
PrivateDirectMessage: () => PrivateDirectMessage,
|
||||
ProblemTracker: () => ProblemTracker,
|
||||
ProfileBadges: () => ProfileBadges,
|
||||
PublicChatsList: () => PublicChatsList,
|
||||
Reaction: () => Reaction,
|
||||
RecommendRelay: () => RecommendRelay,
|
||||
RelayList: () => RelayList,
|
||||
Relaysets: () => Relaysets,
|
||||
Report: () => Report,
|
||||
Reporting: () => Reporting,
|
||||
Repost: () => Repost,
|
||||
Seal: () => Seal,
|
||||
SearchRelaysList: () => SearchRelaysList,
|
||||
ShortTextNote: () => ShortTextNote,
|
||||
Time: () => Time,
|
||||
UserEmojiList: () => UserEmojiList,
|
||||
UserStatuses: () => UserStatuses,
|
||||
Zap: () => Zap,
|
||||
ZapGoal: () => ZapGoal,
|
||||
ZapRequest: () => ZapRequest,
|
||||
classifyKind: () => classifyKind,
|
||||
isAddressableKind: () => isAddressableKind,
|
||||
isEphemeralKind: () => isEphemeralKind,
|
||||
isKind: () => isKind,
|
||||
isRegularKind: () => isRegularKind,
|
||||
isReplaceableKind: () => isReplaceableKind
|
||||
});
|
||||
module.exports = __toCommonJS(kinds_exports);
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i = 0; i < event.tags.length; i++) {
|
||||
let tag = event.tags[i];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// kinds.ts
|
||||
function isRegularKind(kind) {
|
||||
return 1e3 <= kind && kind < 1e4 || [1, 2, 4, 5, 6, 7, 8, 16, 40, 41, 42, 43, 44].includes(kind);
|
||||
}
|
||||
function isReplaceableKind(kind) {
|
||||
return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;
|
||||
}
|
||||
function isEphemeralKind(kind) {
|
||||
return 2e4 <= kind && kind < 3e4;
|
||||
}
|
||||
function isAddressableKind(kind) {
|
||||
return 3e4 <= kind && kind < 4e4;
|
||||
}
|
||||
function classifyKind(kind) {
|
||||
if (isRegularKind(kind))
|
||||
return "regular";
|
||||
if (isReplaceableKind(kind))
|
||||
return "replaceable";
|
||||
if (isEphemeralKind(kind))
|
||||
return "ephemeral";
|
||||
if (isAddressableKind(kind))
|
||||
return "parameterized";
|
||||
return "unknown";
|
||||
}
|
||||
function isKind(event, kind) {
|
||||
const kindAsArray = kind instanceof Array ? kind : [kind];
|
||||
return validateEvent(event) && kindAsArray.includes(event.kind) || false;
|
||||
}
|
||||
var Metadata = 0;
|
||||
var ShortTextNote = 1;
|
||||
var RecommendRelay = 2;
|
||||
var Contacts = 3;
|
||||
var EncryptedDirectMessage = 4;
|
||||
var EventDeletion = 5;
|
||||
var Repost = 6;
|
||||
var Reaction = 7;
|
||||
var BadgeAward = 8;
|
||||
var Seal = 13;
|
||||
var PrivateDirectMessage = 14;
|
||||
var GenericRepost = 16;
|
||||
var ChannelCreation = 40;
|
||||
var ChannelMetadata = 41;
|
||||
var ChannelMessage = 42;
|
||||
var ChannelHideMessage = 43;
|
||||
var ChannelMuteUser = 44;
|
||||
var OpenTimestamps = 1040;
|
||||
var GiftWrap = 1059;
|
||||
var FileMetadata = 1063;
|
||||
var LiveChatMessage = 1311;
|
||||
var ProblemTracker = 1971;
|
||||
var Report = 1984;
|
||||
var Reporting = 1984;
|
||||
var Label = 1985;
|
||||
var CommunityPostApproval = 4550;
|
||||
var JobRequest = 5999;
|
||||
var JobResult = 6999;
|
||||
var JobFeedback = 7e3;
|
||||
var ZapGoal = 9041;
|
||||
var ZapRequest = 9734;
|
||||
var Zap = 9735;
|
||||
var Highlights = 9802;
|
||||
var Mutelist = 1e4;
|
||||
var Pinlist = 10001;
|
||||
var RelayList = 10002;
|
||||
var BookmarkList = 10003;
|
||||
var CommunitiesList = 10004;
|
||||
var PublicChatsList = 10005;
|
||||
var BlockedRelaysList = 10006;
|
||||
var SearchRelaysList = 10007;
|
||||
var InterestsList = 10015;
|
||||
var UserEmojiList = 10030;
|
||||
var DirectMessageRelaysList = 10050;
|
||||
var FileServerPreference = 10096;
|
||||
var NWCWalletInfo = 13194;
|
||||
var LightningPubRPC = 21e3;
|
||||
var ClientAuth = 22242;
|
||||
var NWCWalletRequest = 23194;
|
||||
var NWCWalletResponse = 23195;
|
||||
var NostrConnect = 24133;
|
||||
var HTTPAuth = 27235;
|
||||
var Followsets = 3e4;
|
||||
var Genericlists = 30001;
|
||||
var Relaysets = 30002;
|
||||
var Bookmarksets = 30003;
|
||||
var Curationsets = 30004;
|
||||
var ProfileBadges = 30008;
|
||||
var BadgeDefinition = 30009;
|
||||
var Interestsets = 30015;
|
||||
var CreateOrUpdateStall = 30017;
|
||||
var CreateOrUpdateProduct = 30018;
|
||||
var LongFormArticle = 30023;
|
||||
var DraftLong = 30024;
|
||||
var Emojisets = 30030;
|
||||
var Application = 30078;
|
||||
var LiveEvent = 30311;
|
||||
var UserStatuses = 30315;
|
||||
var ClassifiedListing = 30402;
|
||||
var DraftClassifiedListing = 30403;
|
||||
var Date = 31922;
|
||||
var Time = 31923;
|
||||
var Calendar = 31924;
|
||||
var CalendarEventRSVP = 31925;
|
||||
var Handlerrecommendation = 31989;
|
||||
var Handlerinformation = 31990;
|
||||
var CommunityDefinition = 34550;
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/kinds.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/kinds.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
61
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip04.js
generated
vendored
Normal file
61
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip04.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip04.ts
|
||||
var nip04_exports = {};
|
||||
__export(nip04_exports, {
|
||||
decrypt: () => decrypt,
|
||||
encrypt: () => encrypt
|
||||
});
|
||||
module.exports = __toCommonJS(nip04_exports);
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_aes = require("@noble/ciphers/aes");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip04.ts
|
||||
function encrypt(secretKey, pubkey, text) {
|
||||
const privkey = secretKey instanceof Uint8Array ? (0, import_utils2.bytesToHex)(secretKey) : secretKey;
|
||||
const key = import_secp256k1.secp256k1.getSharedSecret(privkey, "02" + pubkey);
|
||||
const normalizedKey = getNormalizedX(key);
|
||||
let iv = Uint8Array.from((0, import_utils2.randomBytes)(16));
|
||||
let plaintext = utf8Encoder.encode(text);
|
||||
let ciphertext = (0, import_aes.cbc)(normalizedKey, iv).encrypt(plaintext);
|
||||
let ctb64 = import_base.base64.encode(new Uint8Array(ciphertext));
|
||||
let ivb64 = import_base.base64.encode(new Uint8Array(iv.buffer));
|
||||
return `${ctb64}?iv=${ivb64}`;
|
||||
}
|
||||
function decrypt(secretKey, pubkey, data) {
|
||||
const privkey = secretKey instanceof Uint8Array ? (0, import_utils2.bytesToHex)(secretKey) : secretKey;
|
||||
let [ctb64, ivb64] = data.split("?iv=");
|
||||
let key = import_secp256k1.secp256k1.getSharedSecret(privkey, "02" + pubkey);
|
||||
let normalizedKey = getNormalizedX(key);
|
||||
let iv = import_base.base64.decode(ivb64);
|
||||
let ciphertext = import_base.base64.decode(ctb64);
|
||||
let plaintext = (0, import_aes.cbc)(normalizedKey, iv).decrypt(ciphertext);
|
||||
return utf8Decoder.decode(plaintext);
|
||||
}
|
||||
function getNormalizedX(key) {
|
||||
return key.slice(1, 33);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip04.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip04.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip04.ts", "../../utils.ts"],
|
||||
"sourcesContent": ["import { bytesToHex, randomBytes } from '@noble/hashes/utils'\nimport { secp256k1 } from '@noble/curves/secp256k1'\nimport { cbc } from '@noble/ciphers/aes'\nimport { base64 } from '@scure/base'\n\nimport { utf8Decoder, utf8Encoder } from './utils.ts'\n\nexport function encrypt(secretKey: string | Uint8Array, pubkey: string, text: string): string {\n const privkey: string = secretKey instanceof Uint8Array ? bytesToHex(secretKey) : secretKey\n const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)\n const normalizedKey = getNormalizedX(key)\n\n let iv = Uint8Array.from(randomBytes(16))\n let plaintext = utf8Encoder.encode(text)\n\n let ciphertext = cbc(normalizedKey, iv).encrypt(plaintext)\n\n let ctb64 = base64.encode(new Uint8Array(ciphertext))\n let ivb64 = base64.encode(new Uint8Array(iv.buffer))\n\n return `${ctb64}?iv=${ivb64}`\n}\n\nexport function decrypt(secretKey: string | Uint8Array, pubkey: string, data: string): string {\n const privkey: string = secretKey instanceof Uint8Array ? bytesToHex(secretKey) : secretKey\n let [ctb64, ivb64] = data.split('?iv=')\n let key = secp256k1.getSharedSecret(privkey, '02' + pubkey)\n let normalizedKey = getNormalizedX(key)\n\n let iv = base64.decode(ivb64)\n let ciphertext = base64.decode(ctb64)\n\n let plaintext = cbc(normalizedKey, iv).decrypt(ciphertext)\n\n return utf8Decoder.decode(plaintext)\n}\n\nfunction getNormalizedX(key: Uint8Array): Uint8Array {\n return key.slice(1, 33)\n}\n", "import type { Event } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport class QueueNode<V> {\n public value: V\n public next: QueueNode<V> | null = null\n public prev: QueueNode<V> | null = null\n\n constructor(message: V) {\n this.value = message\n }\n}\n\nexport class Queue<V> {\n public first: QueueNode<V> | null\n public last: QueueNode<V> | null\n\n constructor() {\n this.first = null\n this.last = null\n }\n\n enqueue(value: V): boolean {\n const newNode = new QueueNode(value)\n if (!this.last) {\n // list is empty\n this.first = newNode\n this.last = newNode\n } else if (this.last === this.first) {\n // list has a single element\n this.last = newNode\n this.last.prev = this.first\n this.first.next = newNode\n } else {\n // list has elements, add as last\n newNode.prev = this.last\n this.last.next = newNode\n this.last = newNode\n }\n return true\n }\n\n dequeue(): V | null {\n if (!this.first) return null\n\n if (this.first === this.last) {\n const target = this.first\n this.first = null\n this.last = null\n return target.value\n }\n\n const target = this.first\n this.first = target.next\n if (this.first) {\n this.first.prev = null // fix: clean up prev pointer\n }\n\n return target.value\n }\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAAwC;AACxC,uBAA0B;AAC1B,iBAAoB;AACpB,kBAAuB;;;ACEvB,mBAAuC;AAHhC,IAAM,cAA2B,IAAI,YAAY,OAAO;AACxD,IAAM,cAA2B,IAAI,YAAY;;;ADIjD,SAAS,QAAQ,WAAgC,QAAgB,MAAsB;AAC5F,QAAM,UAAkB,qBAAqB,iBAAa,0BAAW,SAAS,IAAI;AAClF,QAAM,MAAM,2BAAU,gBAAgB,SAAS,OAAO,MAAM;AAC5D,QAAM,gBAAgB,eAAe,GAAG;AAExC,MAAI,KAAK,WAAW,SAAK,2BAAY,EAAE,CAAC;AACxC,MAAI,YAAY,YAAY,OAAO,IAAI;AAEvC,MAAI,iBAAa,gBAAI,eAAe,EAAE,EAAE,QAAQ,SAAS;AAEzD,MAAI,QAAQ,mBAAO,OAAO,IAAI,WAAW,UAAU,CAAC;AACpD,MAAI,QAAQ,mBAAO,OAAO,IAAI,WAAW,GAAG,MAAM,CAAC;AAEnD,SAAO,GAAG,YAAY;AACxB;AAEO,SAAS,QAAQ,WAAgC,QAAgB,MAAsB;AAC5F,QAAM,UAAkB,qBAAqB,iBAAa,0BAAW,SAAS,IAAI;AAClF,MAAI,CAAC,OAAO,KAAK,IAAI,KAAK,MAAM,MAAM;AACtC,MAAI,MAAM,2BAAU,gBAAgB,SAAS,OAAO,MAAM;AAC1D,MAAI,gBAAgB,eAAe,GAAG;AAEtC,MAAI,KAAK,mBAAO,OAAO,KAAK;AAC5B,MAAI,aAAa,mBAAO,OAAO,KAAK;AAEpC,MAAI,gBAAY,gBAAI,eAAe,EAAE,EAAE,QAAQ,UAAU;AAEzD,SAAO,YAAY,OAAO,SAAS;AACrC;AAEA,SAAS,eAAe,KAA6B;AACnD,SAAO,IAAI,MAAM,GAAG,EAAE;AACxB;",
|
||||
"names": ["import_utils"]
|
||||
}
|
||||
76
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip05.js
generated
vendored
Normal file
76
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip05.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip05.ts
|
||||
var nip05_exports = {};
|
||||
__export(nip05_exports, {
|
||||
NIP05_REGEX: () => NIP05_REGEX,
|
||||
isNip05: () => isNip05,
|
||||
isValid: () => isValid,
|
||||
queryProfile: () => queryProfile,
|
||||
searchDomain: () => searchDomain,
|
||||
useFetchImplementation: () => useFetchImplementation
|
||||
});
|
||||
module.exports = __toCommonJS(nip05_exports);
|
||||
var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/;
|
||||
var isNip05 = (value) => NIP05_REGEX.test(value || "");
|
||||
var _fetch;
|
||||
try {
|
||||
_fetch = fetch;
|
||||
} catch (_) {
|
||||
null;
|
||||
}
|
||||
function useFetchImplementation(fetchImplementation) {
|
||||
_fetch = fetchImplementation;
|
||||
}
|
||||
async function searchDomain(domain, query = "") {
|
||||
try {
|
||||
const url = `https://${domain}/.well-known/nostr.json?name=${query}`;
|
||||
const res = await _fetch(url, { redirect: "manual" });
|
||||
if (res.status !== 200) {
|
||||
throw Error("Wrong response code");
|
||||
}
|
||||
const json = await res.json();
|
||||
return json.names;
|
||||
} catch (_) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
async function queryProfile(fullname) {
|
||||
const match = fullname.match(NIP05_REGEX);
|
||||
if (!match)
|
||||
return null;
|
||||
const [, name = "_", domain] = match;
|
||||
try {
|
||||
const url = `https://${domain}/.well-known/nostr.json?name=${name}`;
|
||||
const res = await _fetch(url, { redirect: "manual" });
|
||||
if (res.status !== 200) {
|
||||
throw Error("Wrong response code");
|
||||
}
|
||||
const json = await res.json();
|
||||
const pubkey = json.names[name];
|
||||
return pubkey ? { pubkey, relays: json.relays?.[pubkey] } : null;
|
||||
} catch (_e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function isValid(pubkey, nip05) {
|
||||
const res = await queryProfile(nip05);
|
||||
return res ? res.pubkey === pubkey : false;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip05.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip05.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip05.ts"],
|
||||
"sourcesContent": ["import { ProfilePointer } from './nip19.ts'\n\nexport type Nip05 = `${string}@${string}`\n\n/**\n * NIP-05 regex. The localpart is optional, and should be assumed to be `_` otherwise.\n *\n * - 0: full match\n * - 1: name (optional)\n * - 2: domain\n */\nexport const NIP05_REGEX = /^(?:([\\w.+-]+)@)?([\\w_-]+(\\.[\\w_-]+)+)$/\nexport const isNip05 = (value?: string | null): value is Nip05 => NIP05_REGEX.test(value || '')\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _fetch: any\n\ntry {\n _fetch = fetch\n} catch (_) {\n null\n}\n\nexport function useFetchImplementation(fetchImplementation: unknown) {\n _fetch = fetchImplementation\n}\n\nexport async function searchDomain(domain: string, query = ''): Promise<{ [name: string]: string }> {\n try {\n const url = `https://${domain}/.well-known/nostr.json?name=${query}`\n const res = await _fetch(url, { redirect: 'manual' })\n if (res.status !== 200) {\n throw Error('Wrong response code')\n }\n const json = await res.json()\n return json.names\n } catch (_) {\n return {}\n }\n}\n\nexport async function queryProfile(fullname: string): Promise<ProfilePointer | null> {\n const match = fullname.match(NIP05_REGEX)\n if (!match) return null\n\n const [, name = '_', domain] = match\n\n try {\n const url = `https://${domain}/.well-known/nostr.json?name=${name}`\n const res = await _fetch(url, { redirect: 'manual' })\n if (res.status !== 200) {\n throw Error('Wrong response code')\n }\n const json = await res.json()\n\n const pubkey = json.names[name]\n return pubkey ? { pubkey, relays: json.relays?.[pubkey] } : null\n } catch (_e) {\n return null\n }\n}\n\nexport async function isValid(pubkey: string, nip05: Nip05): Promise<boolean> {\n const res = await queryProfile(nip05)\n return res ? res.pubkey === pubkey : false\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,IAAM,cAAc;AACpB,IAAM,UAAU,CAAC,UAA0C,YAAY,KAAK,SAAS,EAAE;AAG9F,IAAI;AAEJ,IAAI;AACF,WAAS;AACX,SAAS,GAAP;AACA;AACF;AAEO,SAAS,uBAAuB,qBAA8B;AACnE,WAAS;AACX;AAEA,eAAsB,aAAa,QAAgB,QAAQ,IAAyC;AAClG,MAAI;AACF,UAAM,MAAM,WAAW,sCAAsC;AAC7D,UAAM,MAAM,MAAM,OAAO,KAAK,EAAE,UAAU,SAAS,CAAC;AACpD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,MAAM,qBAAqB;AAAA,IACnC;AACA,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,WAAO,KAAK;AAAA,EACd,SAAS,GAAP;AACA,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,aAAa,UAAkD;AACnF,QAAM,QAAQ,SAAS,MAAM,WAAW;AACxC,MAAI,CAAC;AAAO,WAAO;AAEnB,QAAM,CAAC,EAAE,OAAO,KAAK,MAAM,IAAI;AAE/B,MAAI;AACF,UAAM,MAAM,WAAW,sCAAsC;AAC7D,UAAM,MAAM,MAAM,OAAO,KAAK,EAAE,UAAU,SAAS,CAAC;AACpD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,MAAM,qBAAqB;AAAA,IACnC;AACA,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,UAAM,SAAS,KAAK,MAAM;AAC1B,WAAO,SAAS,EAAE,QAAQ,QAAQ,KAAK,SAAS,QAAQ,IAAI;AAAA,EAC9D,SAAS,IAAP;AACA,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,QAAQ,QAAgB,OAAgC;AAC5E,QAAM,MAAM,MAAM,aAAa,KAAK;AACpC,SAAO,MAAM,IAAI,WAAW,SAAS;AACvC;",
|
||||
"names": []
|
||||
}
|
||||
82
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip06.js
generated
vendored
Normal file
82
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip06.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip06.ts
|
||||
var nip06_exports = {};
|
||||
__export(nip06_exports, {
|
||||
accountFromExtendedKey: () => accountFromExtendedKey,
|
||||
accountFromSeedWords: () => accountFromSeedWords,
|
||||
extendedKeysFromSeedWords: () => extendedKeysFromSeedWords,
|
||||
generateSeedWords: () => generateSeedWords,
|
||||
privateKeyFromSeedWords: () => privateKeyFromSeedWords,
|
||||
validateWords: () => validateWords
|
||||
});
|
||||
module.exports = __toCommonJS(nip06_exports);
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var import_english = require("@scure/bip39/wordlists/english");
|
||||
var import_bip39 = require("@scure/bip39");
|
||||
var import_bip32 = require("@scure/bip32");
|
||||
var DERIVATION_PATH = `m/44'/1237'`;
|
||||
function privateKeyFromSeedWords(mnemonic, passphrase, accountIndex = 0) {
|
||||
let root = import_bip32.HDKey.fromMasterSeed((0, import_bip39.mnemonicToSeedSync)(mnemonic, passphrase));
|
||||
let privateKey = root.derive(`${DERIVATION_PATH}/${accountIndex}'/0/0`).privateKey;
|
||||
if (!privateKey)
|
||||
throw new Error("could not derive private key");
|
||||
return privateKey;
|
||||
}
|
||||
function accountFromSeedWords(mnemonic, passphrase, accountIndex = 0) {
|
||||
const root = import_bip32.HDKey.fromMasterSeed((0, import_bip39.mnemonicToSeedSync)(mnemonic, passphrase));
|
||||
const seed = root.derive(`${DERIVATION_PATH}/${accountIndex}'/0/0`);
|
||||
const publicKey = (0, import_utils.bytesToHex)(seed.publicKey.slice(1));
|
||||
const privateKey = seed.privateKey;
|
||||
if (!privateKey || !publicKey) {
|
||||
throw new Error("could not derive key pair");
|
||||
}
|
||||
return { privateKey, publicKey };
|
||||
}
|
||||
function extendedKeysFromSeedWords(mnemonic, passphrase, extendedAccountIndex = 0) {
|
||||
let root = import_bip32.HDKey.fromMasterSeed((0, import_bip39.mnemonicToSeedSync)(mnemonic, passphrase));
|
||||
let seed = root.derive(`${DERIVATION_PATH}/${extendedAccountIndex}'`);
|
||||
let privateExtendedKey = seed.privateExtendedKey;
|
||||
let publicExtendedKey = seed.publicExtendedKey;
|
||||
if (!privateExtendedKey && !publicExtendedKey)
|
||||
throw new Error("could not derive extended key pair");
|
||||
return { privateExtendedKey, publicExtendedKey };
|
||||
}
|
||||
function accountFromExtendedKey(base58key, accountIndex = 0) {
|
||||
let extendedKey = import_bip32.HDKey.fromExtendedKey(base58key);
|
||||
let version = base58key.slice(0, 4);
|
||||
let child = extendedKey.deriveChild(0).deriveChild(accountIndex);
|
||||
let publicKey = (0, import_utils.bytesToHex)(child.publicKey.slice(1));
|
||||
if (!publicKey)
|
||||
throw new Error("could not derive public key");
|
||||
if (version === "xprv") {
|
||||
let privateKey = child.privateKey;
|
||||
if (!privateKey)
|
||||
throw new Error("could not derive private key");
|
||||
return { privateKey, publicKey };
|
||||
}
|
||||
return { publicKey };
|
||||
}
|
||||
function generateSeedWords() {
|
||||
return (0, import_bip39.generateMnemonic)(import_english.wordlist);
|
||||
}
|
||||
function validateWords(words) {
|
||||
return (0, import_bip39.validateMnemonic)(words, import_english.wordlist);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip06.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip06.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip06.ts"],
|
||||
"sourcesContent": ["import { bytesToHex } from '@noble/hashes/utils'\nimport { wordlist } from '@scure/bip39/wordlists/english'\nimport { generateMnemonic, mnemonicToSeedSync, validateMnemonic } from '@scure/bip39'\nimport { HDKey } from '@scure/bip32'\n\nconst DERIVATION_PATH = `m/44'/1237'`\n\nexport function privateKeyFromSeedWords(mnemonic: string, passphrase?: string, accountIndex = 0): Uint8Array {\n let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase))\n let privateKey = root.derive(`${DERIVATION_PATH}/${accountIndex}'/0/0`).privateKey\n if (!privateKey) throw new Error('could not derive private key')\n return privateKey\n}\n\nexport function accountFromSeedWords(\n mnemonic: string,\n passphrase?: string,\n accountIndex = 0,\n): {\n privateKey: Uint8Array\n publicKey: string\n} {\n const root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase))\n const seed = root.derive(`${DERIVATION_PATH}/${accountIndex}'/0/0`)\n const publicKey = bytesToHex(seed.publicKey!.slice(1))\n const privateKey = seed.privateKey\n if (!privateKey || !publicKey) {\n throw new Error('could not derive key pair')\n }\n return { privateKey, publicKey }\n}\n\nexport function extendedKeysFromSeedWords(\n mnemonic: string,\n passphrase?: string,\n extendedAccountIndex = 0,\n): {\n privateExtendedKey: string\n publicExtendedKey: string\n} {\n let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase))\n let seed = root.derive(`${DERIVATION_PATH}/${extendedAccountIndex}'`)\n let privateExtendedKey = seed.privateExtendedKey\n let publicExtendedKey = seed.publicExtendedKey\n if (!privateExtendedKey && !publicExtendedKey) throw new Error('could not derive extended key pair')\n return { privateExtendedKey, publicExtendedKey }\n}\n\nexport function accountFromExtendedKey(\n base58key: string,\n accountIndex = 0,\n): {\n privateKey?: Uint8Array\n publicKey: string\n} {\n let extendedKey = HDKey.fromExtendedKey(base58key)\n let version = base58key.slice(0, 4)\n let child = extendedKey.deriveChild(0).deriveChild(accountIndex)\n let publicKey = bytesToHex(child.publicKey!.slice(1))\n if (!publicKey) throw new Error('could not derive public key')\n if (version === 'xprv') {\n let privateKey = child.privateKey!\n if (!privateKey) throw new Error('could not derive private key')\n return { privateKey, publicKey }\n }\n return { publicKey }\n}\n\nexport function generateSeedWords(): string {\n return generateMnemonic(wordlist)\n}\n\nexport function validateWords(words: string): boolean {\n return validateMnemonic(words, wordlist)\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2B;AAC3B,qBAAyB;AACzB,mBAAuE;AACvE,mBAAsB;AAEtB,IAAM,kBAAkB;AAEjB,SAAS,wBAAwB,UAAkB,YAAqB,eAAe,GAAe;AAC3G,MAAI,OAAO,mBAAM,mBAAe,iCAAmB,UAAU,UAAU,CAAC;AACxE,MAAI,aAAa,KAAK,OAAO,GAAG,mBAAmB,mBAAmB,EAAE;AACxE,MAAI,CAAC;AAAY,UAAM,IAAI,MAAM,8BAA8B;AAC/D,SAAO;AACT;AAEO,SAAS,qBACd,UACA,YACA,eAAe,GAIf;AACA,QAAM,OAAO,mBAAM,mBAAe,iCAAmB,UAAU,UAAU,CAAC;AAC1E,QAAM,OAAO,KAAK,OAAO,GAAG,mBAAmB,mBAAmB;AAClE,QAAM,gBAAY,yBAAW,KAAK,UAAW,MAAM,CAAC,CAAC;AACrD,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,cAAc,CAAC,WAAW;AAC7B,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AACA,SAAO,EAAE,YAAY,UAAU;AACjC;AAEO,SAAS,0BACd,UACA,YACA,uBAAuB,GAIvB;AACA,MAAI,OAAO,mBAAM,mBAAe,iCAAmB,UAAU,UAAU,CAAC;AACxE,MAAI,OAAO,KAAK,OAAO,GAAG,mBAAmB,uBAAuB;AACpE,MAAI,qBAAqB,KAAK;AAC9B,MAAI,oBAAoB,KAAK;AAC7B,MAAI,CAAC,sBAAsB,CAAC;AAAmB,UAAM,IAAI,MAAM,oCAAoC;AACnG,SAAO,EAAE,oBAAoB,kBAAkB;AACjD;AAEO,SAAS,uBACd,WACA,eAAe,GAIf;AACA,MAAI,cAAc,mBAAM,gBAAgB,SAAS;AACjD,MAAI,UAAU,UAAU,MAAM,GAAG,CAAC;AAClC,MAAI,QAAQ,YAAY,YAAY,CAAC,EAAE,YAAY,YAAY;AAC/D,MAAI,gBAAY,yBAAW,MAAM,UAAW,MAAM,CAAC,CAAC;AACpD,MAAI,CAAC;AAAW,UAAM,IAAI,MAAM,6BAA6B;AAC7D,MAAI,YAAY,QAAQ;AACtB,QAAI,aAAa,MAAM;AACvB,QAAI,CAAC;AAAY,YAAM,IAAI,MAAM,8BAA8B;AAC/D,WAAO,EAAE,YAAY,UAAU;AAAA,EACjC;AACA,SAAO,EAAE,UAAU;AACrB;AAEO,SAAS,oBAA4B;AAC1C,aAAO,+BAAiB,uBAAQ;AAClC;AAEO,SAAS,cAAc,OAAwB;AACpD,aAAO,+BAAiB,OAAO,uBAAQ;AACzC;",
|
||||
"names": []
|
||||
}
|
||||
18
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip07.js
generated
vendored
Normal file
18
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip07.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip07.ts
|
||||
var nip07_exports = {};
|
||||
module.exports = __toCommonJS(nip07_exports);
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip07.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip07.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip07.ts"],
|
||||
"sourcesContent": ["import { EventTemplate, VerifiedEvent } from './core.ts'\n\nexport interface WindowNostr {\n getPublicKey(): Promise<string>\n signEvent(event: EventTemplate): Promise<VerifiedEvent>\n nip04?: {\n encrypt(pubkey: string, plaintext: string): Promise<string>\n decrypt(pubkey: string, ciphertext: string): Promise<string>\n }\n nip44?: {\n encrypt(pubkey: string, plaintext: string): Promise<string>\n decrypt(pubkey: string, ciphertext: string): Promise<string>\n }\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;",
|
||||
"names": []
|
||||
}
|
||||
124
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip10.js
generated
vendored
Normal file
124
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip10.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip10.ts
|
||||
var nip10_exports = {};
|
||||
__export(nip10_exports, {
|
||||
parse: () => parse
|
||||
});
|
||||
module.exports = __toCommonJS(nip10_exports);
|
||||
function parse(event) {
|
||||
const result = {
|
||||
reply: void 0,
|
||||
root: void 0,
|
||||
mentions: [],
|
||||
profiles: [],
|
||||
quotes: []
|
||||
};
|
||||
let maybeParent;
|
||||
let maybeRoot;
|
||||
for (let i = event.tags.length - 1; i >= 0; i--) {
|
||||
const tag = event.tags[i];
|
||||
if (tag[0] === "e" && tag[1]) {
|
||||
const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag;
|
||||
const eventPointer = {
|
||||
id: eTagEventId,
|
||||
relays: eTagRelayUrl ? [eTagRelayUrl] : [],
|
||||
author: eTagAuthor
|
||||
};
|
||||
if (eTagMarker === "root") {
|
||||
result.root = eventPointer;
|
||||
continue;
|
||||
}
|
||||
if (eTagMarker === "reply") {
|
||||
result.reply = eventPointer;
|
||||
continue;
|
||||
}
|
||||
if (eTagMarker === "mention") {
|
||||
result.mentions.push(eventPointer);
|
||||
continue;
|
||||
}
|
||||
if (!maybeParent) {
|
||||
maybeParent = eventPointer;
|
||||
} else {
|
||||
maybeRoot = eventPointer;
|
||||
}
|
||||
result.mentions.push(eventPointer);
|
||||
continue;
|
||||
}
|
||||
if (tag[0] === "q" && tag[1]) {
|
||||
const [_, eTagEventId, eTagRelayUrl] = tag;
|
||||
result.quotes.push({
|
||||
id: eTagEventId,
|
||||
relays: eTagRelayUrl ? [eTagRelayUrl] : []
|
||||
});
|
||||
}
|
||||
if (tag[0] === "p" && tag[1]) {
|
||||
result.profiles.push({
|
||||
pubkey: tag[1],
|
||||
relays: tag[2] ? [tag[2]] : []
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!result.root) {
|
||||
result.root = maybeRoot || maybeParent || result.reply;
|
||||
}
|
||||
if (!result.reply) {
|
||||
result.reply = maybeParent || result.root;
|
||||
}
|
||||
;
|
||||
[result.reply, result.root].forEach((ref) => {
|
||||
if (!ref)
|
||||
return;
|
||||
let idx = result.mentions.indexOf(ref);
|
||||
if (idx !== -1) {
|
||||
result.mentions.splice(idx, 1);
|
||||
}
|
||||
if (ref.author) {
|
||||
let author = result.profiles.find((p) => p.pubkey === ref.author);
|
||||
if (author && author.relays) {
|
||||
if (!ref.relays) {
|
||||
ref.relays = [];
|
||||
}
|
||||
author.relays.forEach((url) => {
|
||||
if (ref.relays?.indexOf(url) === -1)
|
||||
ref.relays.push(url);
|
||||
});
|
||||
author.relays = ref.relays;
|
||||
}
|
||||
}
|
||||
});
|
||||
result.mentions.forEach((ref) => {
|
||||
if (ref.author) {
|
||||
let author = result.profiles.find((p) => p.pubkey === ref.author);
|
||||
if (author && author.relays) {
|
||||
if (!ref.relays) {
|
||||
ref.relays = [];
|
||||
}
|
||||
author.relays.forEach((url) => {
|
||||
if (ref.relays.indexOf(url) === -1)
|
||||
ref.relays.push(url);
|
||||
});
|
||||
author.relays = ref.relays;
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip10.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip10.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip10.ts"],
|
||||
"sourcesContent": ["import type { Event } from './core.ts'\nimport type { EventPointer, ProfilePointer } from './nip19.ts'\n\nexport function parse(event: Pick<Event, 'tags'>): {\n /**\n * Pointer to the root of the thread.\n */\n root: EventPointer | undefined\n\n /**\n * Pointer to a \"parent\" event that parsed event replies to (responded to).\n */\n reply: EventPointer | undefined\n\n /**\n * Pointers to events that may or may not be in the reply chain.\n */\n mentions: EventPointer[]\n\n /**\n * Pointers to events that were directly quoted.\n */\n quotes: EventPointer[]\n\n /**\n * List of pubkeys that are involved in the thread in no particular order.\n */\n profiles: ProfilePointer[]\n} {\n const result: ReturnType<typeof parse> = {\n reply: undefined,\n root: undefined,\n mentions: [],\n profiles: [],\n quotes: [],\n }\n\n let maybeParent: EventPointer | undefined\n let maybeRoot: EventPointer | undefined\n\n for (let i = event.tags.length - 1; i >= 0; i--) {\n const tag = event.tags[i]\n\n if (tag[0] === 'e' && tag[1]) {\n const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag as [\n string,\n string,\n undefined | string,\n undefined | string,\n undefined | string,\n ]\n\n const eventPointer: EventPointer = {\n id: eTagEventId,\n relays: eTagRelayUrl ? [eTagRelayUrl] : [],\n author: eTagAuthor,\n }\n\n if (eTagMarker === 'root') {\n result.root = eventPointer\n continue\n }\n\n if (eTagMarker === 'reply') {\n result.reply = eventPointer\n continue\n }\n\n if (eTagMarker === 'mention') {\n result.mentions.push(eventPointer)\n continue\n }\n\n if (!maybeParent) {\n maybeParent = eventPointer\n } else {\n maybeRoot = eventPointer\n }\n\n result.mentions.push(eventPointer)\n continue\n }\n\n if (tag[0] === 'q' && tag[1]) {\n const [_, eTagEventId, eTagRelayUrl] = tag as [string, string, undefined | string]\n result.quotes.push({\n id: eTagEventId,\n relays: eTagRelayUrl ? [eTagRelayUrl] : [],\n })\n }\n\n if (tag[0] === 'p' && tag[1]) {\n result.profiles.push({\n pubkey: tag[1],\n relays: tag[2] ? [tag[2]] : [],\n })\n continue\n }\n }\n\n // get legacy (positional) markers, set reply to root and vice-versa if one of them is missing\n if (!result.root) {\n result.root = maybeRoot || maybeParent || result.reply\n }\n if (!result.reply) {\n result.reply = maybeParent || result.root\n }\n\n // remove root and reply from mentions, inherit relay hints from authors if any\n ;[result.reply, result.root].forEach(ref => {\n if (!ref) return\n\n let idx = result.mentions.indexOf(ref)\n if (idx !== -1) {\n result.mentions.splice(idx, 1)\n }\n if (ref.author) {\n let author = result.profiles.find(p => p.pubkey === ref.author)\n if (author && author.relays) {\n if (!ref.relays) {\n ref.relays = []\n }\n author.relays.forEach(url => {\n if (ref.relays!?.indexOf(url) === -1) ref.relays!.push(url)\n })\n author.relays = ref.relays\n }\n }\n })\n\n result.mentions.forEach(ref => {\n if (ref!.author) {\n let author = result.profiles.find(p => p.pubkey === ref.author)\n if (author && author.relays) {\n if (!ref.relays) {\n ref.relays = []\n }\n author.relays.forEach(url => {\n if (ref.relays!.indexOf(url) === -1) ref.relays!.push(url)\n })\n author.relays = ref.relays\n }\n }\n })\n\n return result\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,SAAS,MAAM,OAyBpB;AACA,QAAM,SAAmC;AAAA,IACvC,OAAO;AAAA,IACP,MAAM;AAAA,IACN,UAAU,CAAC;AAAA,IACX,UAAU,CAAC;AAAA,IACX,QAAQ,CAAC;AAAA,EACX;AAEA,MAAI;AACJ,MAAI;AAEJ,WAAS,IAAI,MAAM,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,UAAM,MAAM,MAAM,KAAK;AAEvB,QAAI,IAAI,OAAO,OAAO,IAAI,IAAI;AAC5B,YAAM,CAAC,GAAG,aAAa,cAAc,YAAY,UAAU,IAAI;AAQ/D,YAAM,eAA6B;AAAA,QACjC,IAAI;AAAA,QACJ,QAAQ,eAAe,CAAC,YAAY,IAAI,CAAC;AAAA,QACzC,QAAQ;AAAA,MACV;AAEA,UAAI,eAAe,QAAQ;AACzB,eAAO,OAAO;AACd;AAAA,MACF;AAEA,UAAI,eAAe,SAAS;AAC1B,eAAO,QAAQ;AACf;AAAA,MACF;AAEA,UAAI,eAAe,WAAW;AAC5B,eAAO,SAAS,KAAK,YAAY;AACjC;AAAA,MACF;AAEA,UAAI,CAAC,aAAa;AAChB,sBAAc;AAAA,MAChB,OAAO;AACL,oBAAY;AAAA,MACd;AAEA,aAAO,SAAS,KAAK,YAAY;AACjC;AAAA,IACF;AAEA,QAAI,IAAI,OAAO,OAAO,IAAI,IAAI;AAC5B,YAAM,CAAC,GAAG,aAAa,YAAY,IAAI;AACvC,aAAO,OAAO,KAAK;AAAA,QACjB,IAAI;AAAA,QACJ,QAAQ,eAAe,CAAC,YAAY,IAAI,CAAC;AAAA,MAC3C,CAAC;AAAA,IACH;AAEA,QAAI,IAAI,OAAO,OAAO,IAAI,IAAI;AAC5B,aAAO,SAAS,KAAK;AAAA,QACnB,QAAQ,IAAI;AAAA,QACZ,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAAA,MAC/B,CAAC;AACD;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,OAAO,MAAM;AAChB,WAAO,OAAO,aAAa,eAAe,OAAO;AAAA,EACnD;AACA,MAAI,CAAC,OAAO,OAAO;AACjB,WAAO,QAAQ,eAAe,OAAO;AAAA,EACvC;AAGA;AAAC,GAAC,OAAO,OAAO,OAAO,IAAI,EAAE,QAAQ,SAAO;AAC1C,QAAI,CAAC;AAAK;AAEV,QAAI,MAAM,OAAO,SAAS,QAAQ,GAAG;AACrC,QAAI,QAAQ,IAAI;AACd,aAAO,SAAS,OAAO,KAAK,CAAC;AAAA,IAC/B;AACA,QAAI,IAAI,QAAQ;AACd,UAAI,SAAS,OAAO,SAAS,KAAK,OAAK,EAAE,WAAW,IAAI,MAAM;AAC9D,UAAI,UAAU,OAAO,QAAQ;AAC3B,YAAI,CAAC,IAAI,QAAQ;AACf,cAAI,SAAS,CAAC;AAAA,QAChB;AACA,eAAO,OAAO,QAAQ,SAAO;AAC3B,cAAI,IAAI,QAAS,QAAQ,GAAG,MAAM;AAAI,gBAAI,OAAQ,KAAK,GAAG;AAAA,QAC5D,CAAC;AACD,eAAO,SAAS,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,SAAS,QAAQ,SAAO;AAC7B,QAAI,IAAK,QAAQ;AACf,UAAI,SAAS,OAAO,SAAS,KAAK,OAAK,EAAE,WAAW,IAAI,MAAM;AAC9D,UAAI,UAAU,OAAO,QAAQ;AAC3B,YAAI,CAAC,IAAI,QAAQ;AACf,cAAI,SAAS,CAAC;AAAA,QAChB;AACA,eAAO,OAAO,QAAQ,SAAO;AAC3B,cAAI,IAAI,OAAQ,QAAQ,GAAG,MAAM;AAAI,gBAAI,OAAQ,KAAK,GAAG;AAAA,QAC3D,CAAC;AACD,eAAO,SAAS,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
|
||||
"names": []
|
||||
}
|
||||
39
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip11.js
generated
vendored
Normal file
39
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip11.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip11.ts
|
||||
var nip11_exports = {};
|
||||
__export(nip11_exports, {
|
||||
fetchRelayInformation: () => fetchRelayInformation,
|
||||
useFetchImplementation: () => useFetchImplementation
|
||||
});
|
||||
module.exports = __toCommonJS(nip11_exports);
|
||||
var _fetch;
|
||||
try {
|
||||
_fetch = fetch;
|
||||
} catch {
|
||||
}
|
||||
function useFetchImplementation(fetchImplementation) {
|
||||
_fetch = fetchImplementation;
|
||||
}
|
||||
async function fetchRelayInformation(url) {
|
||||
return await (await fetch(url.replace("ws://", "http://").replace("wss://", "https://"), {
|
||||
headers: { Accept: "application/nostr+json" }
|
||||
})).json();
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip11.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip11.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
73
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip13.js
generated
vendored
Normal file
73
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip13.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip13.ts
|
||||
var nip13_exports = {};
|
||||
__export(nip13_exports, {
|
||||
fastEventHash: () => fastEventHash,
|
||||
getPow: () => getPow,
|
||||
minePow: () => minePow
|
||||
});
|
||||
module.exports = __toCommonJS(nip13_exports);
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip13.ts
|
||||
function getPow(hex) {
|
||||
let count = 0;
|
||||
for (let i = 0; i < 64; i += 8) {
|
||||
const nibble = parseInt(hex.substring(i, i + 8), 16);
|
||||
if (nibble === 0) {
|
||||
count += 32;
|
||||
} else {
|
||||
count += Math.clz32(nibble);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
function minePow(unsigned, difficulty) {
|
||||
let count = 0;
|
||||
const event = unsigned;
|
||||
const tag = ["nonce", count.toString(), difficulty.toString()];
|
||||
event.tags.push(tag);
|
||||
while (true) {
|
||||
const now = Math.floor(new Date().getTime() / 1e3);
|
||||
if (now !== event.created_at) {
|
||||
count = 0;
|
||||
event.created_at = now;
|
||||
}
|
||||
tag[1] = (++count).toString();
|
||||
event.id = fastEventHash(event);
|
||||
if (getPow(event.id) >= difficulty) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
function fastEventHash(evt) {
|
||||
return (0, import_utils2.bytesToHex)(
|
||||
(0, import_sha256.sha256)(utf8Encoder.encode(JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content])))
|
||||
);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip13.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip13.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip13.ts", "../../utils.ts"],
|
||||
"sourcesContent": ["import { bytesToHex } from '@noble/hashes/utils'\nimport { type UnsignedEvent, type Event } from './pure.ts'\nimport { sha256 } from '@noble/hashes/sha256'\n\nimport { utf8Encoder } from './utils.ts'\n\n/** Get POW difficulty from a Nostr hex ID. */\nexport function getPow(hex: string): number {\n let count = 0\n\n for (let i = 0; i < 64; i += 8) {\n const nibble = parseInt(hex.substring(i, i + 8), 16)\n if (nibble === 0) {\n count += 32\n } else {\n count += Math.clz32(nibble)\n break\n }\n }\n\n return count\n}\n\n/**\n * Mine an event with the desired POW. This function mutates the event.\n * Note that this operation is synchronous and should be run in a worker context to avoid blocking the main thread.\n */\nexport function minePow(unsigned: UnsignedEvent, difficulty: number): Omit<Event, 'sig'> {\n let count = 0\n\n const event = unsigned as Omit<Event, 'sig'>\n const tag = ['nonce', count.toString(), difficulty.toString()]\n\n event.tags.push(tag)\n\n while (true) {\n const now = Math.floor(new Date().getTime() / 1000)\n\n if (now !== event.created_at) {\n count = 0\n event.created_at = now\n }\n\n tag[1] = (++count).toString()\n\n event.id = fastEventHash(event)\n\n if (getPow(event.id) >= difficulty) {\n break\n }\n }\n\n return event\n}\n\nexport function fastEventHash(evt: UnsignedEvent): string {\n return bytesToHex(\n sha256(utf8Encoder.encode(JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]))),\n )\n}\n", "import type { Event } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport class QueueNode<V> {\n public value: V\n public next: QueueNode<V> | null = null\n public prev: QueueNode<V> | null = null\n\n constructor(message: V) {\n this.value = message\n }\n}\n\nexport class Queue<V> {\n public first: QueueNode<V> | null\n public last: QueueNode<V> | null\n\n constructor() {\n this.first = null\n this.last = null\n }\n\n enqueue(value: V): boolean {\n const newNode = new QueueNode(value)\n if (!this.last) {\n // list is empty\n this.first = newNode\n this.last = newNode\n } else if (this.last === this.first) {\n // list has a single element\n this.last = newNode\n this.last.prev = this.first\n this.first.next = newNode\n } else {\n // list has elements, add as last\n newNode.prev = this.last\n this.last.next = newNode\n this.last = newNode\n }\n return true\n }\n\n dequeue(): V | null {\n if (!this.first) return null\n\n if (this.first === this.last) {\n const target = this.first\n this.first = null\n this.last = null\n return target.value\n }\n\n const target = this.first\n this.first = target.next\n if (this.first) {\n this.first.prev = null // fix: clean up prev pointer\n }\n\n return target.value\n }\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA2B;AAE3B,oBAAuB;;;ACGvB,mBAAuC;AAHhC,IAAM,cAA2B,IAAI,YAAY,OAAO;AACxD,IAAM,cAA2B,IAAI,YAAY;;;ADIjD,SAAS,OAAO,KAAqB;AAC1C,MAAI,QAAQ;AAEZ,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG;AAC9B,UAAM,SAAS,SAAS,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE;AACnD,QAAI,WAAW,GAAG;AAChB,eAAS;AAAA,IACX,OAAO;AACL,eAAS,KAAK,MAAM,MAAM;AAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,QAAQ,UAAyB,YAAwC;AACvF,MAAI,QAAQ;AAEZ,QAAM,QAAQ;AACd,QAAM,MAAM,CAAC,SAAS,MAAM,SAAS,GAAG,WAAW,SAAS,CAAC;AAE7D,QAAM,KAAK,KAAK,GAAG;AAEnB,SAAO,MAAM;AACX,UAAM,MAAM,KAAK,MAAM,IAAI,KAAK,EAAE,QAAQ,IAAI,GAAI;AAElD,QAAI,QAAQ,MAAM,YAAY;AAC5B,cAAQ;AACR,YAAM,aAAa;AAAA,IACrB;AAEA,QAAI,MAAM,EAAE,OAAO,SAAS;AAE5B,UAAM,KAAK,cAAc,KAAK;AAE9B,QAAI,OAAO,MAAM,EAAE,KAAK,YAAY;AAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,KAA4B;AACxD,aAAO;AAAA,QACL,sBAAO,YAAY,OAAO,KAAK,UAAU,CAAC,GAAG,IAAI,QAAQ,IAAI,YAAY,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC;AAAA,EAC7G;AACF;",
|
||||
"names": ["import_utils"]
|
||||
}
|
||||
321
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip17.js
generated
vendored
Normal file
321
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip17.js
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip17.ts
|
||||
var nip17_exports = {};
|
||||
__export(nip17_exports, {
|
||||
unwrapEvent: () => unwrapEvent2,
|
||||
unwrapManyEvents: () => unwrapManyEvents2,
|
||||
wrapEvent: () => wrapEvent2,
|
||||
wrapManyEvents: () => wrapManyEvents
|
||||
});
|
||||
module.exports = __toCommonJS(nip17_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var Seal = 13;
|
||||
var PrivateDirectMessage = 14;
|
||||
var GiftWrap = 1059;
|
||||
|
||||
// nip44.ts
|
||||
var import_chacha = require("@noble/ciphers/chacha");
|
||||
var import_utils4 = require("@noble/ciphers/utils");
|
||||
var import_secp256k12 = require("@noble/curves/secp256k1");
|
||||
var import_hkdf = require("@noble/hashes/hkdf");
|
||||
var import_hmac = require("@noble/hashes/hmac");
|
||||
var import_sha2562 = require("@noble/hashes/sha256");
|
||||
var import_utils5 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
var minPlaintextSize = 1;
|
||||
var maxPlaintextSize = 65535;
|
||||
function getConversationKey(privkeyA, pubkeyB) {
|
||||
const sharedX = import_secp256k12.secp256k1.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
|
||||
return (0, import_hkdf.extract)(import_sha2562.sha256, sharedX, "nip44-v2");
|
||||
}
|
||||
function getMessageKeys(conversationKey, nonce) {
|
||||
const keys = (0, import_hkdf.expand)(import_sha2562.sha256, conversationKey, nonce, 76);
|
||||
return {
|
||||
chacha_key: keys.subarray(0, 32),
|
||||
chacha_nonce: keys.subarray(32, 44),
|
||||
hmac_key: keys.subarray(44, 76)
|
||||
};
|
||||
}
|
||||
function calcPaddedLen(len) {
|
||||
if (!Number.isSafeInteger(len) || len < 1)
|
||||
throw new Error("expected positive integer");
|
||||
if (len <= 32)
|
||||
return 32;
|
||||
const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;
|
||||
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
|
||||
return chunk * (Math.floor((len - 1) / chunk) + 1);
|
||||
}
|
||||
function writeU16BE(num) {
|
||||
if (!Number.isSafeInteger(num) || num < minPlaintextSize || num > maxPlaintextSize)
|
||||
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
|
||||
const arr = new Uint8Array(2);
|
||||
new DataView(arr.buffer).setUint16(0, num, false);
|
||||
return arr;
|
||||
}
|
||||
function pad(plaintext) {
|
||||
const unpadded = utf8Encoder.encode(plaintext);
|
||||
const unpaddedLen = unpadded.length;
|
||||
const prefix = writeU16BE(unpaddedLen);
|
||||
const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen);
|
||||
return (0, import_utils5.concatBytes)(prefix, unpadded, suffix);
|
||||
}
|
||||
function unpad(padded) {
|
||||
const unpaddedLen = new DataView(padded.buffer).getUint16(0);
|
||||
const unpadded = padded.subarray(2, 2 + unpaddedLen);
|
||||
if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + calcPaddedLen(unpaddedLen))
|
||||
throw new Error("invalid padding");
|
||||
return utf8Decoder.decode(unpadded);
|
||||
}
|
||||
function hmacAad(key, message, aad) {
|
||||
if (aad.length !== 32)
|
||||
throw new Error("AAD associated data must be 32 bytes");
|
||||
const combined = (0, import_utils5.concatBytes)(aad, message);
|
||||
return (0, import_hmac.hmac)(import_sha2562.sha256, key, combined);
|
||||
}
|
||||
function decodePayload(payload) {
|
||||
if (typeof payload !== "string")
|
||||
throw new Error("payload must be a valid string");
|
||||
const plen = payload.length;
|
||||
if (plen < 132 || plen > 87472)
|
||||
throw new Error("invalid payload length: " + plen);
|
||||
if (payload[0] === "#")
|
||||
throw new Error("unknown encryption version");
|
||||
let data;
|
||||
try {
|
||||
data = import_base.base64.decode(payload);
|
||||
} catch (error) {
|
||||
throw new Error("invalid base64: " + error.message);
|
||||
}
|
||||
const dlen = data.length;
|
||||
if (dlen < 99 || dlen > 65603)
|
||||
throw new Error("invalid data length: " + dlen);
|
||||
const vers = data[0];
|
||||
if (vers !== 2)
|
||||
throw new Error("unknown encryption version " + vers);
|
||||
return {
|
||||
nonce: data.subarray(1, 33),
|
||||
ciphertext: data.subarray(33, -32),
|
||||
mac: data.subarray(-32)
|
||||
};
|
||||
}
|
||||
function encrypt(plaintext, conversationKey, nonce = (0, import_utils5.randomBytes)(32)) {
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const padded = pad(plaintext);
|
||||
const ciphertext = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, padded);
|
||||
const mac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
return import_base.base64.encode((0, import_utils5.concatBytes)(new Uint8Array([2]), nonce, ciphertext, mac));
|
||||
}
|
||||
function decrypt(payload, conversationKey) {
|
||||
const { nonce, ciphertext, mac } = decodePayload(payload);
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const calculatedMac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
if (!(0, import_utils4.equalBytes)(calculatedMac, mac))
|
||||
throw new Error("invalid MAC");
|
||||
const padded = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, ciphertext);
|
||||
return unpad(padded);
|
||||
}
|
||||
|
||||
// nip59.ts
|
||||
var TWO_DAYS = 2 * 24 * 60 * 60;
|
||||
var now = () => Math.round(Date.now() / 1e3);
|
||||
var randomNow = () => Math.round(now() - Math.random() * TWO_DAYS);
|
||||
var nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey);
|
||||
var nip44Encrypt = (data, privateKey, publicKey) => encrypt(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey));
|
||||
var nip44Decrypt = (data, privateKey) => JSON.parse(decrypt(data.content, nip44ConversationKey(privateKey, data.pubkey)));
|
||||
function createRumor(event, privateKey) {
|
||||
const rumor = {
|
||||
created_at: now(),
|
||||
content: "",
|
||||
tags: [],
|
||||
...event,
|
||||
pubkey: getPublicKey(privateKey)
|
||||
};
|
||||
rumor.id = getEventHash(rumor);
|
||||
return rumor;
|
||||
}
|
||||
function createSeal(rumor, privateKey, recipientPublicKey) {
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: Seal,
|
||||
content: nip44Encrypt(rumor, privateKey, recipientPublicKey),
|
||||
created_at: randomNow(),
|
||||
tags: []
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
}
|
||||
function createWrap(seal, recipientPublicKey) {
|
||||
const randomKey = generateSecretKey();
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: GiftWrap,
|
||||
content: nip44Encrypt(seal, randomKey, recipientPublicKey),
|
||||
created_at: randomNow(),
|
||||
tags: [["p", recipientPublicKey]]
|
||||
},
|
||||
randomKey
|
||||
);
|
||||
}
|
||||
function wrapEvent(event, senderPrivateKey, recipientPublicKey) {
|
||||
const rumor = createRumor(event, senderPrivateKey);
|
||||
const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey);
|
||||
return createWrap(seal, recipientPublicKey);
|
||||
}
|
||||
function unwrapEvent(wrap, recipientPrivateKey) {
|
||||
const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey);
|
||||
return nip44Decrypt(unwrappedSeal, recipientPrivateKey);
|
||||
}
|
||||
function unwrapManyEvents(wrappedEvents, recipientPrivateKey) {
|
||||
let unwrappedEvents = [];
|
||||
wrappedEvents.forEach((e) => {
|
||||
unwrappedEvents.push(unwrapEvent(e, recipientPrivateKey));
|
||||
});
|
||||
unwrappedEvents.sort((a, b) => a.created_at - b.created_at);
|
||||
return unwrappedEvents;
|
||||
}
|
||||
|
||||
// nip17.ts
|
||||
function createEvent(recipients, message, conversationTitle, replyTo) {
|
||||
const baseEvent = {
|
||||
created_at: Math.ceil(Date.now() / 1e3),
|
||||
kind: PrivateDirectMessage,
|
||||
tags: [],
|
||||
content: message
|
||||
};
|
||||
const recipientsArray = Array.isArray(recipients) ? recipients : [recipients];
|
||||
recipientsArray.forEach(({ publicKey, relayUrl }) => {
|
||||
baseEvent.tags.push(relayUrl ? ["p", publicKey, relayUrl] : ["p", publicKey]);
|
||||
});
|
||||
if (replyTo) {
|
||||
baseEvent.tags.push(["e", replyTo.eventId, replyTo.relayUrl || "", "reply"]);
|
||||
}
|
||||
if (conversationTitle) {
|
||||
baseEvent.tags.push(["subject", conversationTitle]);
|
||||
}
|
||||
return baseEvent;
|
||||
}
|
||||
function wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo) {
|
||||
const event = createEvent(recipient, message, conversationTitle, replyTo);
|
||||
return wrapEvent(event, senderPrivateKey, recipient.publicKey);
|
||||
}
|
||||
function wrapManyEvents(senderPrivateKey, recipients, message, conversationTitle, replyTo) {
|
||||
if (!recipients || recipients.length === 0) {
|
||||
throw new Error("At least one recipient is required.");
|
||||
}
|
||||
const senderPublicKey = getPublicKey(senderPrivateKey);
|
||||
return [{ publicKey: senderPublicKey }, ...recipients].map(
|
||||
(recipient) => wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo)
|
||||
);
|
||||
}
|
||||
var unwrapEvent2 = unwrapEvent;
|
||||
var unwrapManyEvents2 = unwrapManyEvents;
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip17.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip17.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
188
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip18.js
generated
vendored
Normal file
188
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip18.js
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip18.ts
|
||||
var nip18_exports = {};
|
||||
__export(nip18_exports, {
|
||||
finishRepostEvent: () => finishRepostEvent,
|
||||
getRepostedEvent: () => getRepostedEvent,
|
||||
getRepostedEventPointer: () => getRepostedEventPointer
|
||||
});
|
||||
module.exports = __toCommonJS(nip18_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var ShortTextNote = 1;
|
||||
var Repost = 6;
|
||||
var GenericRepost = 16;
|
||||
|
||||
// nip18.ts
|
||||
function finishRepostEvent(t, reposted, relayUrl, privateKey) {
|
||||
let kind;
|
||||
const tags = [...t.tags ?? [], ["e", reposted.id, relayUrl], ["p", reposted.pubkey]];
|
||||
if (reposted.kind === ShortTextNote) {
|
||||
kind = Repost;
|
||||
} else {
|
||||
kind = GenericRepost;
|
||||
tags.push(["k", String(reposted.kind)]);
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind,
|
||||
tags,
|
||||
content: t.content === "" || reposted.tags?.find((tag) => tag[0] === "-") ? "" : JSON.stringify(reposted),
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
}
|
||||
function getRepostedEventPointer(event) {
|
||||
if (![Repost, GenericRepost].includes(event.kind)) {
|
||||
return void 0;
|
||||
}
|
||||
let lastETag;
|
||||
let lastPTag;
|
||||
for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) {
|
||||
const tag = event.tags[i2];
|
||||
if (tag.length >= 2) {
|
||||
if (tag[0] === "e" && lastETag === void 0) {
|
||||
lastETag = tag;
|
||||
} else if (tag[0] === "p" && lastPTag === void 0) {
|
||||
lastPTag = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastETag === void 0) {
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
id: lastETag[1],
|
||||
relays: [lastETag[2], lastPTag?.[2]].filter((x) => typeof x === "string"),
|
||||
author: lastPTag?.[1]
|
||||
};
|
||||
}
|
||||
function getRepostedEvent(event, { skipVerification } = {}) {
|
||||
const pointer = getRepostedEventPointer(event);
|
||||
if (pointer === void 0 || event.content === "") {
|
||||
return void 0;
|
||||
}
|
||||
let repostedEvent;
|
||||
try {
|
||||
repostedEvent = JSON.parse(event.content);
|
||||
} catch (error) {
|
||||
return void 0;
|
||||
}
|
||||
if (repostedEvent.id !== pointer.id) {
|
||||
return void 0;
|
||||
}
|
||||
if (!skipVerification && !verifyEvent(repostedEvent)) {
|
||||
return void 0;
|
||||
}
|
||||
return repostedEvent;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip18.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip18.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
217
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip19.js
generated
vendored
Normal file
217
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip19.js
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip19.ts
|
||||
var nip19_exports = {};
|
||||
__export(nip19_exports, {
|
||||
BECH32_REGEX: () => BECH32_REGEX,
|
||||
Bech32MaxSize: () => Bech32MaxSize,
|
||||
NostrTypeGuard: () => NostrTypeGuard,
|
||||
decode: () => decode,
|
||||
decodeNostrURI: () => decodeNostrURI,
|
||||
encodeBytes: () => encodeBytes,
|
||||
naddrEncode: () => naddrEncode,
|
||||
neventEncode: () => neventEncode,
|
||||
noteEncode: () => noteEncode,
|
||||
nprofileEncode: () => nprofileEncode,
|
||||
npubEncode: () => npubEncode,
|
||||
nsecEncode: () => nsecEncode
|
||||
});
|
||||
module.exports = __toCommonJS(nip19_exports);
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip19.ts
|
||||
var NostrTypeGuard = {
|
||||
isNProfile: (value) => /^nprofile1[a-z\d]+$/.test(value || ""),
|
||||
isNEvent: (value) => /^nevent1[a-z\d]+$/.test(value || ""),
|
||||
isNAddr: (value) => /^naddr1[a-z\d]+$/.test(value || ""),
|
||||
isNSec: (value) => /^nsec1[a-z\d]{58}$/.test(value || ""),
|
||||
isNPub: (value) => /^npub1[a-z\d]{58}$/.test(value || ""),
|
||||
isNote: (value) => /^note1[a-z\d]+$/.test(value || ""),
|
||||
isNcryptsec: (value) => /^ncryptsec1[a-z\d]+$/.test(value || "")
|
||||
};
|
||||
var Bech32MaxSize = 5e3;
|
||||
var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;
|
||||
function integerToUint8Array(number) {
|
||||
const uint8Array = new Uint8Array(4);
|
||||
uint8Array[0] = number >> 24 & 255;
|
||||
uint8Array[1] = number >> 16 & 255;
|
||||
uint8Array[2] = number >> 8 & 255;
|
||||
uint8Array[3] = number & 255;
|
||||
return uint8Array;
|
||||
}
|
||||
function decodeNostrURI(nip19code) {
|
||||
try {
|
||||
if (nip19code.startsWith("nostr:"))
|
||||
nip19code = nip19code.substring(6);
|
||||
return decode(nip19code);
|
||||
} catch (_err) {
|
||||
return { type: "invalid", data: null };
|
||||
}
|
||||
}
|
||||
function decode(code) {
|
||||
let { prefix, words } = import_base.bech32.decode(code, Bech32MaxSize);
|
||||
let data = new Uint8Array(import_base.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: (0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[0][0]),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
||||
author: tlv[2]?.[0] ? (0, import_utils2.bytesToHex)(tlv[2][0]) : void 0,
|
||||
kind: tlv[3]?.[0] ? parseInt((0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[2][0]),
|
||||
kind: parseInt((0, import_utils2.bytesToHex)(tlv[3][0]), 16),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
||||
}
|
||||
};
|
||||
}
|
||||
case "nsec":
|
||||
return { type: prefix, data };
|
||||
case "npub":
|
||||
case "note":
|
||||
return { type: prefix, data: (0, import_utils2.bytesToHex)(data) };
|
||||
default:
|
||||
throw new Error(`unknown prefix ${prefix}`);
|
||||
}
|
||||
}
|
||||
function parseTLV(data) {
|
||||
let result = {};
|
||||
let rest = data;
|
||||
while (rest.length > 0) {
|
||||
let t = rest[0];
|
||||
let l = rest[1];
|
||||
let v = rest.slice(2, 2 + l);
|
||||
rest = rest.slice(2 + l);
|
||||
if (v.length < l)
|
||||
throw new Error(`not enough data to read on TLV ${t}`);
|
||||
result[t] = result[t] || [];
|
||||
result[t].push(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function nsecEncode(key) {
|
||||
return encodeBytes("nsec", key);
|
||||
}
|
||||
function npubEncode(hex) {
|
||||
return encodeBytes("npub", (0, import_utils2.hexToBytes)(hex));
|
||||
}
|
||||
function noteEncode(hex) {
|
||||
return encodeBytes("note", (0, import_utils2.hexToBytes)(hex));
|
||||
}
|
||||
function encodeBech32(prefix, data) {
|
||||
let words = import_base.bech32.toWords(data);
|
||||
return import_base.bech32.encode(prefix, words, Bech32MaxSize);
|
||||
}
|
||||
function encodeBytes(prefix, bytes) {
|
||||
return encodeBech32(prefix, bytes);
|
||||
}
|
||||
function nprofileEncode(profile) {
|
||||
let data = encodeTLV({
|
||||
0: [(0, import_utils2.hexToBytes)(profile.pubkey)],
|
||||
1: (profile.relays || []).map((url) => utf8Encoder.encode(url))
|
||||
});
|
||||
return encodeBech32("nprofile", data);
|
||||
}
|
||||
function neventEncode(event) {
|
||||
let kindArray;
|
||||
if (event.kind !== void 0) {
|
||||
kindArray = integerToUint8Array(event.kind);
|
||||
}
|
||||
let data = encodeTLV({
|
||||
0: [(0, import_utils2.hexToBytes)(event.id)],
|
||||
1: (event.relays || []).map((url) => utf8Encoder.encode(url)),
|
||||
2: event.author ? [(0, import_utils2.hexToBytes)(event.author)] : [],
|
||||
3: kindArray ? [new Uint8Array(kindArray)] : []
|
||||
});
|
||||
return encodeBech32("nevent", data);
|
||||
}
|
||||
function naddrEncode(addr) {
|
||||
let kind = new ArrayBuffer(4);
|
||||
new DataView(kind).setUint32(0, addr.kind, false);
|
||||
let data = encodeTLV({
|
||||
0: [utf8Encoder.encode(addr.identifier)],
|
||||
1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),
|
||||
2: [(0, import_utils2.hexToBytes)(addr.pubkey)],
|
||||
3: [new Uint8Array(kind)]
|
||||
});
|
||||
return encodeBech32("naddr", data);
|
||||
}
|
||||
function encodeTLV(tlv) {
|
||||
let entries = [];
|
||||
Object.entries(tlv).reverse().forEach(([t, vs]) => {
|
||||
vs.forEach((v) => {
|
||||
let entry = new Uint8Array(v.length + 2);
|
||||
entry.set([parseInt(t)], 0);
|
||||
entry.set([v.length], 1);
|
||||
entry.set(v, 2);
|
||||
entries.push(entry);
|
||||
});
|
||||
});
|
||||
return (0, import_utils2.concatBytes)(...entries);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip19.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip19.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
140
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip21.js
generated
vendored
Normal file
140
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip21.js
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip21.ts
|
||||
var nip21_exports = {};
|
||||
__export(nip21_exports, {
|
||||
NOSTR_URI_REGEX: () => NOSTR_URI_REGEX,
|
||||
parse: () => parse,
|
||||
test: () => test
|
||||
});
|
||||
module.exports = __toCommonJS(nip21_exports);
|
||||
|
||||
// nip19.ts
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip19.ts
|
||||
var Bech32MaxSize = 5e3;
|
||||
var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;
|
||||
function decode(code) {
|
||||
let { prefix, words } = import_base.bech32.decode(code, Bech32MaxSize);
|
||||
let data = new Uint8Array(import_base.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: (0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[0][0]),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
||||
author: tlv[2]?.[0] ? (0, import_utils2.bytesToHex)(tlv[2][0]) : void 0,
|
||||
kind: tlv[3]?.[0] ? parseInt((0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[2][0]),
|
||||
kind: parseInt((0, import_utils2.bytesToHex)(tlv[3][0]), 16),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
||||
}
|
||||
};
|
||||
}
|
||||
case "nsec":
|
||||
return { type: prefix, data };
|
||||
case "npub":
|
||||
case "note":
|
||||
return { type: prefix, data: (0, import_utils2.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;
|
||||
}
|
||||
|
||||
// nip21.ts
|
||||
var NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`);
|
||||
function test(value) {
|
||||
return typeof value === "string" && new RegExp(`^${NOSTR_URI_REGEX.source}$`).test(value);
|
||||
}
|
||||
function parse(uri) {
|
||||
const match = uri.match(new RegExp(`^${NOSTR_URI_REGEX.source}$`));
|
||||
if (!match)
|
||||
throw new Error(`Invalid Nostr URI: ${uri}`);
|
||||
return {
|
||||
uri: match[0],
|
||||
value: match[1],
|
||||
decoded: decode(match[1])
|
||||
};
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip21.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip21.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
159
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip25.js
generated
vendored
Normal file
159
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip25.js
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip25.ts
|
||||
var nip25_exports = {};
|
||||
__export(nip25_exports, {
|
||||
finishReactionEvent: () => finishReactionEvent,
|
||||
getReactedEventPointer: () => getReactedEventPointer
|
||||
});
|
||||
module.exports = __toCommonJS(nip25_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var Reaction = 7;
|
||||
|
||||
// nip25.ts
|
||||
function finishReactionEvent(t, reacted, privateKey) {
|
||||
const inheritedTags = reacted.tags.filter((tag) => tag.length >= 2 && (tag[0] === "e" || tag[0] === "p"));
|
||||
return finalizeEvent(
|
||||
{
|
||||
...t,
|
||||
kind: Reaction,
|
||||
tags: [...t.tags ?? [], ...inheritedTags, ["e", reacted.id], ["p", reacted.pubkey]],
|
||||
content: t.content ?? "+"
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
}
|
||||
function getReactedEventPointer(event) {
|
||||
if (event.kind !== Reaction) {
|
||||
return void 0;
|
||||
}
|
||||
let lastETag;
|
||||
let lastPTag;
|
||||
for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) {
|
||||
const tag = event.tags[i2];
|
||||
if (tag.length >= 2) {
|
||||
if (tag[0] === "e" && lastETag === void 0) {
|
||||
lastETag = tag;
|
||||
} else if (tag[0] === "p" && lastPTag === void 0) {
|
||||
lastPTag = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastETag === void 0 || lastPTag === void 0) {
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
id: lastETag[1],
|
||||
relays: [lastETag[2], lastPTag[2]].filter((x) => x !== void 0),
|
||||
author: lastPTag[1]
|
||||
};
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip25.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip25.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
229
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip27.js
generated
vendored
Normal file
229
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip27.js
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip27.ts
|
||||
var nip27_exports = {};
|
||||
__export(nip27_exports, {
|
||||
parse: () => parse
|
||||
});
|
||||
module.exports = __toCommonJS(nip27_exports);
|
||||
|
||||
// nip19.ts
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip19.ts
|
||||
var Bech32MaxSize = 5e3;
|
||||
function decode(code) {
|
||||
let { prefix, words } = import_base.bech32.decode(code, Bech32MaxSize);
|
||||
let data = new Uint8Array(import_base.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: (0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[0][0]),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
||||
author: tlv[2]?.[0] ? (0, import_utils2.bytesToHex)(tlv[2][0]) : void 0,
|
||||
kind: tlv[3]?.[0] ? parseInt((0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[2][0]),
|
||||
kind: parseInt((0, import_utils2.bytesToHex)(tlv[3][0]), 16),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
||||
}
|
||||
};
|
||||
}
|
||||
case "nsec":
|
||||
return { type: prefix, data };
|
||||
case "npub":
|
||||
case "note":
|
||||
return { type: prefix, data: (0, import_utils2.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;
|
||||
}
|
||||
|
||||
// nip27.ts
|
||||
var noCharacter = /\W/m;
|
||||
var noURLCharacter = /\W |\W$|$|,| /m;
|
||||
function* parse(content) {
|
||||
const max = content.length;
|
||||
let prevIndex = 0;
|
||||
let index = 0;
|
||||
while (index < max) {
|
||||
let u = content.indexOf(":", index);
|
||||
if (u === -1) {
|
||||
break;
|
||||
}
|
||||
if (content.substring(u - 5, u) === "nostr") {
|
||||
const m = content.substring(u + 60).match(noCharacter);
|
||||
const end = m ? u + 60 + m.index : max;
|
||||
try {
|
||||
let pointer;
|
||||
let { data, type } = decode(content.substring(u + 1, end));
|
||||
switch (type) {
|
||||
case "npub":
|
||||
pointer = { pubkey: data };
|
||||
break;
|
||||
case "nsec":
|
||||
case "note":
|
||||
index = end + 1;
|
||||
continue;
|
||||
default:
|
||||
pointer = data;
|
||||
}
|
||||
if (prevIndex !== u - 5) {
|
||||
yield { type: "text", text: content.substring(prevIndex, u - 5) };
|
||||
}
|
||||
yield { type: "reference", pointer };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
} catch (_err) {
|
||||
index = u + 1;
|
||||
continue;
|
||||
}
|
||||
} else if (content.substring(u - 5, u) === "https" || content.substring(u - 4, u) === "http") {
|
||||
const m = content.substring(u + 4).match(noURLCharacter);
|
||||
const end = m ? u + 4 + m.index : max;
|
||||
const prefixLen = content[u - 1] === "s" ? 5 : 4;
|
||||
try {
|
||||
let url = new URL(content.substring(u - prefixLen, end));
|
||||
if (url.hostname.indexOf(".") === -1) {
|
||||
throw new Error("invalid url");
|
||||
}
|
||||
if (prevIndex !== u - prefixLen) {
|
||||
yield { type: "text", text: content.substring(prevIndex, u - prefixLen) };
|
||||
}
|
||||
if (/\.(png|jpe?g|gif|webp)$/i.test(url.pathname)) {
|
||||
yield { type: "image", url: url.toString() };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
}
|
||||
if (/\.(mp4|avi|webm|mkv)$/i.test(url.pathname)) {
|
||||
yield { type: "video", url: url.toString() };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
}
|
||||
if (/\.(mp3|aac|ogg|opus)$/i.test(url.pathname)) {
|
||||
yield { type: "audio", url: url.toString() };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
}
|
||||
yield { type: "url", url: url.toString() };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
} catch (_err) {
|
||||
index = end + 1;
|
||||
continue;
|
||||
}
|
||||
} else if (content.substring(u - 3, u) === "wss" || content.substring(u - 2, u) === "ws") {
|
||||
const m = content.substring(u + 4).match(noURLCharacter);
|
||||
const end = m ? u + 4 + m.index : max;
|
||||
const prefixLen = content[u - 1] === "s" ? 3 : 2;
|
||||
try {
|
||||
let url = new URL(content.substring(u - prefixLen, end));
|
||||
if (url.hostname.indexOf(".") === -1) {
|
||||
throw new Error("invalid ws url");
|
||||
}
|
||||
if (prevIndex !== u - prefixLen) {
|
||||
yield { type: "text", text: content.substring(prevIndex, u - prefixLen) };
|
||||
}
|
||||
yield { type: "relay", url: url.toString() };
|
||||
index = end;
|
||||
prevIndex = index;
|
||||
continue;
|
||||
} catch (_err) {
|
||||
index = end + 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
index = u + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (prevIndex !== max) {
|
||||
yield { type: "text", text: content.substring(prevIndex) };
|
||||
}
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip27.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip27.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
220
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip28.js
generated
vendored
Normal file
220
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip28.js
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip28.ts
|
||||
var nip28_exports = {};
|
||||
__export(nip28_exports, {
|
||||
channelCreateEvent: () => channelCreateEvent,
|
||||
channelHideMessageEvent: () => channelHideMessageEvent,
|
||||
channelMessageEvent: () => channelMessageEvent,
|
||||
channelMetadataEvent: () => channelMetadataEvent,
|
||||
channelMuteUserEvent: () => channelMuteUserEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip28_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var ChannelCreation = 40;
|
||||
var ChannelMetadata = 41;
|
||||
var ChannelMessage = 42;
|
||||
var ChannelHideMessage = 43;
|
||||
var ChannelMuteUser = 44;
|
||||
|
||||
// nip28.ts
|
||||
var channelCreateEvent = (t, privateKey) => {
|
||||
let content;
|
||||
if (typeof t.content === "object") {
|
||||
content = JSON.stringify(t.content);
|
||||
} else if (typeof t.content === "string") {
|
||||
content = t.content;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelCreation,
|
||||
tags: [...t.tags ?? []],
|
||||
content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
};
|
||||
var channelMetadataEvent = (t, privateKey) => {
|
||||
let content;
|
||||
if (typeof t.content === "object") {
|
||||
content = JSON.stringify(t.content);
|
||||
} else if (typeof t.content === "string") {
|
||||
content = t.content;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMetadata,
|
||||
tags: [["e", t.channel_create_event_id], ...t.tags ?? []],
|
||||
content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
};
|
||||
var channelMessageEvent = (t, privateKey) => {
|
||||
const tags = [["e", t.channel_create_event_id, t.relay_url, "root"]];
|
||||
if (t.reply_to_channel_message_event_id) {
|
||||
tags.push(["e", t.reply_to_channel_message_event_id, t.relay_url, "reply"]);
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMessage,
|
||||
tags: [...tags, ...t.tags ?? []],
|
||||
content: t.content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
};
|
||||
var channelHideMessageEvent = (t, privateKey) => {
|
||||
let content;
|
||||
if (typeof t.content === "object") {
|
||||
content = JSON.stringify(t.content);
|
||||
} else if (typeof t.content === "string") {
|
||||
content = t.content;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelHideMessage,
|
||||
tags: [["e", t.channel_message_event_id], ...t.tags ?? []],
|
||||
content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
};
|
||||
var channelMuteUserEvent = (t, privateKey) => {
|
||||
let content;
|
||||
if (typeof t.content === "object") {
|
||||
content = JSON.stringify(t.content);
|
||||
} else if (typeof t.content === "string") {
|
||||
content = t.content;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMuteUser,
|
||||
tags: [["p", t.pubkey_to_mute], ...t.tags ?? []],
|
||||
content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip28.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip28.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
495
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip29.js
generated
vendored
Normal file
495
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip29.js
generated
vendored
Normal file
@@ -0,0 +1,495 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip29.ts
|
||||
var nip29_exports = {};
|
||||
__export(nip29_exports, {
|
||||
GroupAdminPermission: () => GroupAdminPermission,
|
||||
encodeGroupReference: () => encodeGroupReference,
|
||||
fetchGroupAdminsEvent: () => fetchGroupAdminsEvent,
|
||||
fetchGroupMembersEvent: () => fetchGroupMembersEvent,
|
||||
fetchGroupMetadataEvent: () => fetchGroupMetadataEvent,
|
||||
fetchRelayInformationByGroupReference: () => fetchRelayInformationByGroupReference,
|
||||
generateGroupAdminsEventTemplate: () => generateGroupAdminsEventTemplate,
|
||||
generateGroupMembersEventTemplate: () => generateGroupMembersEventTemplate,
|
||||
generateGroupMetadataEventTemplate: () => generateGroupMetadataEventTemplate,
|
||||
getNormalizedRelayURLByGroupReference: () => getNormalizedRelayURLByGroupReference,
|
||||
loadGroup: () => loadGroup,
|
||||
loadGroupFromCode: () => loadGroupFromCode,
|
||||
parseGroupAdminsEvent: () => parseGroupAdminsEvent,
|
||||
parseGroupCode: () => parseGroupCode,
|
||||
parseGroupMembersEvent: () => parseGroupMembersEvent,
|
||||
parseGroupMetadataEvent: () => parseGroupMetadataEvent,
|
||||
subscribeRelayGroupsMetadataEvents: () => subscribeRelayGroupsMetadataEvents,
|
||||
validateGroupAdminsEvent: () => validateGroupAdminsEvent,
|
||||
validateGroupMembersEvent: () => validateGroupMembersEvent,
|
||||
validateGroupMetadataEvent: () => validateGroupMetadataEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip29_exports);
|
||||
|
||||
// nip11.ts
|
||||
var _fetch;
|
||||
try {
|
||||
_fetch = fetch;
|
||||
} catch {
|
||||
}
|
||||
async function fetchRelayInformation(url) {
|
||||
return await (await fetch(url.replace("ws://", "http://").replace("wss://", "https://"), {
|
||||
headers: { Accept: "application/nostr+json" }
|
||||
})).json();
|
||||
}
|
||||
|
||||
// nip19.ts
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
// nip19.ts
|
||||
var NostrTypeGuard = {
|
||||
isNProfile: (value) => /^nprofile1[a-z\d]+$/.test(value || ""),
|
||||
isNEvent: (value) => /^nevent1[a-z\d]+$/.test(value || ""),
|
||||
isNAddr: (value) => /^naddr1[a-z\d]+$/.test(value || ""),
|
||||
isNSec: (value) => /^nsec1[a-z\d]{58}$/.test(value || ""),
|
||||
isNPub: (value) => /^npub1[a-z\d]{58}$/.test(value || ""),
|
||||
isNote: (value) => /^note1[a-z\d]+$/.test(value || ""),
|
||||
isNcryptsec: (value) => /^ncryptsec1[a-z\d]+$/.test(value || "")
|
||||
};
|
||||
var Bech32MaxSize = 5e3;
|
||||
function decode(code) {
|
||||
let { prefix, words } = import_base.bech32.decode(code, Bech32MaxSize);
|
||||
let data = new Uint8Array(import_base.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: (0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[0][0]),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
||||
author: tlv[2]?.[0] ? (0, import_utils2.bytesToHex)(tlv[2][0]) : void 0,
|
||||
kind: tlv[3]?.[0] ? parseInt((0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[2][0]),
|
||||
kind: parseInt((0, import_utils2.bytesToHex)(tlv[3][0]), 16),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
||||
}
|
||||
};
|
||||
}
|
||||
case "nsec":
|
||||
return { type: prefix, data };
|
||||
case "npub":
|
||||
case "note":
|
||||
return { type: prefix, data: (0, import_utils2.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;
|
||||
}
|
||||
|
||||
// nip29.ts
|
||||
var GroupAdminPermission = /* @__PURE__ */ ((GroupAdminPermission2) => {
|
||||
GroupAdminPermission2["AddUser"] = "add-user";
|
||||
GroupAdminPermission2["EditMetadata"] = "edit-metadata";
|
||||
GroupAdminPermission2["DeleteEvent"] = "delete-event";
|
||||
GroupAdminPermission2["RemoveUser"] = "remove-user";
|
||||
GroupAdminPermission2["AddPermission"] = "add-permission";
|
||||
GroupAdminPermission2["RemovePermission"] = "remove-permission";
|
||||
GroupAdminPermission2["EditGroupStatus"] = "edit-group-status";
|
||||
GroupAdminPermission2["PutUser"] = "put-user";
|
||||
GroupAdminPermission2["CreateGroup"] = "create-group";
|
||||
GroupAdminPermission2["DeleteGroup"] = "delete-group";
|
||||
GroupAdminPermission2["CreateInvite"] = "create-invite";
|
||||
return GroupAdminPermission2;
|
||||
})(GroupAdminPermission || {});
|
||||
function generateGroupMetadataEventTemplate(group) {
|
||||
const tags = [["d", group.metadata.id]];
|
||||
group.metadata.name && tags.push(["name", group.metadata.name]);
|
||||
group.metadata.picture && tags.push(["picture", group.metadata.picture]);
|
||||
group.metadata.about && tags.push(["about", group.metadata.about]);
|
||||
group.metadata.isPublic && tags.push(["public"]);
|
||||
group.metadata.isOpen && tags.push(["open"]);
|
||||
return {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: 39e3,
|
||||
tags
|
||||
};
|
||||
}
|
||||
function validateGroupMetadataEvent(event) {
|
||||
if (event.kind !== 39e3)
|
||||
return false;
|
||||
if (!event.pubkey)
|
||||
return false;
|
||||
const requiredTags = ["d"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function generateGroupAdminsEventTemplate(group, admins) {
|
||||
const tags = [["d", group.metadata.id]];
|
||||
for (const admin of admins) {
|
||||
tags.push(["p", admin.pubkey, admin.label || "", ...admin.permissions]);
|
||||
}
|
||||
return {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: 39001,
|
||||
tags
|
||||
};
|
||||
}
|
||||
function validateGroupAdminsEvent(event) {
|
||||
if (event.kind !== 39001)
|
||||
return false;
|
||||
const requiredTags = ["d"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
for (const [tag, _value, _label, ...permissions] of event.tags) {
|
||||
if (tag !== "p")
|
||||
continue;
|
||||
for (let i = 0; i < permissions.length; i += 1) {
|
||||
if (typeof permissions[i] !== "string")
|
||||
return false;
|
||||
if (!Object.values(GroupAdminPermission).includes(permissions[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function generateGroupMembersEventTemplate(group, members) {
|
||||
const tags = [["d", group.metadata.id]];
|
||||
for (const member of members) {
|
||||
tags.push(["p", member.pubkey, member.label || ""]);
|
||||
}
|
||||
return {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: 39002,
|
||||
tags
|
||||
};
|
||||
}
|
||||
function validateGroupMembersEvent(event) {
|
||||
if (event.kind !== 39002)
|
||||
return false;
|
||||
const requiredTags = ["d"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function getNormalizedRelayURLByGroupReference(groupReference) {
|
||||
return normalizeURL(groupReference.host);
|
||||
}
|
||||
async function fetchRelayInformationByGroupReference(groupReference) {
|
||||
const normalizedRelayURL = getNormalizedRelayURLByGroupReference(groupReference);
|
||||
return fetchRelayInformation(normalizedRelayURL);
|
||||
}
|
||||
async function fetchGroupMetadataEvent({
|
||||
pool,
|
||||
groupReference,
|
||||
relayInformation,
|
||||
normalizedRelayURL
|
||||
}) {
|
||||
if (!normalizedRelayURL) {
|
||||
normalizedRelayURL = getNormalizedRelayURLByGroupReference(groupReference);
|
||||
}
|
||||
if (!relayInformation) {
|
||||
relayInformation = await fetchRelayInformation(normalizedRelayURL);
|
||||
}
|
||||
const groupMetadataEvent = await pool.get([normalizedRelayURL], {
|
||||
kinds: [39e3],
|
||||
authors: [relayInformation.pubkey],
|
||||
"#d": [groupReference.id]
|
||||
});
|
||||
if (!groupMetadataEvent)
|
||||
throw new Error(`group '${groupReference.id}' not found on ${normalizedRelayURL}`);
|
||||
return groupMetadataEvent;
|
||||
}
|
||||
function parseGroupMetadataEvent(event) {
|
||||
if (!validateGroupMetadataEvent(event))
|
||||
throw new Error("invalid group metadata event");
|
||||
const metadata = {
|
||||
id: "",
|
||||
pubkey: event.pubkey
|
||||
};
|
||||
for (const [tag, value] of event.tags) {
|
||||
switch (tag) {
|
||||
case "d":
|
||||
metadata.id = value;
|
||||
break;
|
||||
case "name":
|
||||
metadata.name = value;
|
||||
break;
|
||||
case "picture":
|
||||
metadata.picture = value;
|
||||
break;
|
||||
case "about":
|
||||
metadata.about = value;
|
||||
break;
|
||||
case "public":
|
||||
metadata.isPublic = true;
|
||||
break;
|
||||
case "open":
|
||||
metadata.isOpen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
async function fetchGroupAdminsEvent({
|
||||
pool,
|
||||
groupReference,
|
||||
relayInformation,
|
||||
normalizedRelayURL
|
||||
}) {
|
||||
if (!normalizedRelayURL) {
|
||||
normalizedRelayURL = getNormalizedRelayURLByGroupReference(groupReference);
|
||||
}
|
||||
if (!relayInformation) {
|
||||
relayInformation = await fetchRelayInformation(normalizedRelayURL);
|
||||
}
|
||||
const groupAdminsEvent = await pool.get([normalizedRelayURL], {
|
||||
kinds: [39001],
|
||||
authors: [relayInformation.pubkey],
|
||||
"#d": [groupReference.id]
|
||||
});
|
||||
if (!groupAdminsEvent)
|
||||
throw new Error(`admins for group '${groupReference.id}' not found on ${normalizedRelayURL}`);
|
||||
return groupAdminsEvent;
|
||||
}
|
||||
function parseGroupAdminsEvent(event) {
|
||||
if (!validateGroupAdminsEvent(event))
|
||||
throw new Error("invalid group admins event");
|
||||
const admins = [];
|
||||
for (const [tag, value, label, ...permissions] of event.tags) {
|
||||
if (tag !== "p")
|
||||
continue;
|
||||
admins.push({
|
||||
pubkey: value,
|
||||
label,
|
||||
permissions
|
||||
});
|
||||
}
|
||||
return admins;
|
||||
}
|
||||
async function fetchGroupMembersEvent({
|
||||
pool,
|
||||
groupReference,
|
||||
relayInformation,
|
||||
normalizedRelayURL
|
||||
}) {
|
||||
if (!normalizedRelayURL) {
|
||||
normalizedRelayURL = getNormalizedRelayURLByGroupReference(groupReference);
|
||||
}
|
||||
if (!relayInformation) {
|
||||
relayInformation = await fetchRelayInformation(normalizedRelayURL);
|
||||
}
|
||||
const groupMembersEvent = await pool.get([normalizedRelayURL], {
|
||||
kinds: [39002],
|
||||
authors: [relayInformation.pubkey],
|
||||
"#d": [groupReference.id]
|
||||
});
|
||||
if (!groupMembersEvent)
|
||||
throw new Error(`members for group '${groupReference.id}' not found on ${normalizedRelayURL}`);
|
||||
return groupMembersEvent;
|
||||
}
|
||||
function parseGroupMembersEvent(event) {
|
||||
if (!validateGroupMembersEvent(event))
|
||||
throw new Error("invalid group members event");
|
||||
const members = [];
|
||||
for (const [tag, value, label] of event.tags) {
|
||||
if (tag !== "p")
|
||||
continue;
|
||||
members.push({
|
||||
pubkey: value,
|
||||
label
|
||||
});
|
||||
}
|
||||
return members;
|
||||
}
|
||||
async function loadGroup({
|
||||
pool,
|
||||
groupReference,
|
||||
normalizedRelayURL,
|
||||
relayInformation
|
||||
}) {
|
||||
if (!normalizedRelayURL) {
|
||||
normalizedRelayURL = getNormalizedRelayURLByGroupReference(groupReference);
|
||||
}
|
||||
if (!relayInformation) {
|
||||
relayInformation = await fetchRelayInformation(normalizedRelayURL);
|
||||
}
|
||||
const metadataEvent = await fetchGroupMetadataEvent({ pool, groupReference, normalizedRelayURL, relayInformation });
|
||||
const metadata = parseGroupMetadataEvent(metadataEvent);
|
||||
const adminsEvent = await fetchGroupAdminsEvent({ pool, groupReference, normalizedRelayURL, relayInformation });
|
||||
const admins = parseGroupAdminsEvent(adminsEvent);
|
||||
const membersEvent = await fetchGroupMembersEvent({ pool, groupReference, normalizedRelayURL, relayInformation });
|
||||
const members = parseGroupMembersEvent(membersEvent);
|
||||
const group = {
|
||||
relay: normalizedRelayURL,
|
||||
metadata,
|
||||
admins,
|
||||
members,
|
||||
reference: groupReference
|
||||
};
|
||||
return group;
|
||||
}
|
||||
async function loadGroupFromCode(pool, code) {
|
||||
const groupReference = parseGroupCode(code);
|
||||
if (!groupReference)
|
||||
throw new Error("invalid group code");
|
||||
return loadGroup({ pool, groupReference });
|
||||
}
|
||||
function parseGroupCode(code) {
|
||||
if (NostrTypeGuard.isNAddr(code)) {
|
||||
try {
|
||||
let { data } = decode(code);
|
||||
let { relays, identifier } = data;
|
||||
if (!relays || relays.length === 0)
|
||||
return null;
|
||||
let host = relays[0];
|
||||
if (host.startsWith("wss://")) {
|
||||
host = host.slice(6);
|
||||
}
|
||||
return { host, id: identifier };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
} else if (code.split("'").length === 2) {
|
||||
let spl = code.split("'");
|
||||
return { host: spl[0], id: spl[1] };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function encodeGroupReference(gr) {
|
||||
const { host, id } = gr;
|
||||
const normalizedHost = host.replace(/^(https?:\/\/|wss?:\/\/)/, "");
|
||||
return `${normalizedHost}'${id}`;
|
||||
}
|
||||
function subscribeRelayGroupsMetadataEvents({
|
||||
pool,
|
||||
relayURL,
|
||||
onError,
|
||||
onEvent,
|
||||
onConnect
|
||||
}) {
|
||||
let sub;
|
||||
const normalizedRelayURL = normalizeURL(relayURL);
|
||||
fetchRelayInformation(normalizedRelayURL).then(async (info) => {
|
||||
const abstractedRelay = await pool.ensureRelay(normalizedRelayURL);
|
||||
onConnect?.();
|
||||
sub = abstractedRelay.prepareSubscription(
|
||||
[
|
||||
{
|
||||
kinds: [39e3],
|
||||
limit: 50,
|
||||
authors: [info.pubkey]
|
||||
}
|
||||
],
|
||||
{
|
||||
onevent(event) {
|
||||
onEvent(event);
|
||||
}
|
||||
}
|
||||
);
|
||||
}).catch((err) => {
|
||||
sub.close();
|
||||
onError(err);
|
||||
});
|
||||
return () => sub.close();
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip29.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip29.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
53
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip30.js
generated
vendored
Normal file
53
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip30.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip30.ts
|
||||
var nip30_exports = {};
|
||||
__export(nip30_exports, {
|
||||
EMOJI_SHORTCODE_REGEX: () => EMOJI_SHORTCODE_REGEX,
|
||||
matchAll: () => matchAll,
|
||||
regex: () => regex,
|
||||
replaceAll: () => replaceAll
|
||||
});
|
||||
module.exports = __toCommonJS(nip30_exports);
|
||||
var EMOJI_SHORTCODE_REGEX = /:(\w+):/;
|
||||
var regex = () => new RegExp(`\\B${EMOJI_SHORTCODE_REGEX.source}\\B`, "g");
|
||||
function* matchAll(content) {
|
||||
const matches = content.matchAll(regex());
|
||||
for (const match of matches) {
|
||||
try {
|
||||
const [shortcode, name] = match;
|
||||
yield {
|
||||
shortcode,
|
||||
name,
|
||||
start: match.index,
|
||||
end: match.index + shortcode.length
|
||||
};
|
||||
} catch (_e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function replaceAll(content, replacer) {
|
||||
return content.replaceAll(regex(), (shortcode, name) => {
|
||||
return replacer({
|
||||
shortcode,
|
||||
name
|
||||
});
|
||||
});
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip30.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip30.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip30.ts"],
|
||||
"sourcesContent": ["/** Regex for a single emoji shortcode. */\nexport const EMOJI_SHORTCODE_REGEX = /:(\\w+):/\n\n/** Regex to find emoji shortcodes in content. */\nexport const regex = (): RegExp => new RegExp(`\\\\B${EMOJI_SHORTCODE_REGEX.source}\\\\B`, 'g')\n\n/** Represents a Nostr custom emoji. */\nexport interface CustomEmoji {\n /** The matched emoji name with colons. */\n shortcode: `:${string}:`\n /** The matched emoji name without colons. */\n name: string\n}\n\n/** Match result for a custom emoji in text content. */\nexport interface CustomEmojiMatch extends CustomEmoji {\n /** Index where the emoji begins in the text content. */\n start: number\n /** Index where the emoji ends in the text content. */\n end: number\n}\n\n/** Find all custom emoji shortcodes. */\nexport function* matchAll(content: string): Iterable<CustomEmojiMatch> {\n const matches = content.matchAll(regex())\n\n for (const match of matches) {\n try {\n const [shortcode, name] = match\n\n yield {\n shortcode: shortcode as `:${string}:`,\n name,\n start: match.index!,\n end: match.index! + shortcode.length,\n }\n } catch (_e) {\n // do nothing\n }\n }\n}\n\n/** Replace all emoji shortcodes in the content. */\nexport function replaceAll(content: string, replacer: (match: CustomEmoji) => string): string {\n return content.replaceAll(regex(), (shortcode, name) => {\n return replacer({\n shortcode: shortcode as `:${string}:`,\n name,\n })\n })\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACO,IAAM,wBAAwB;AAG9B,IAAM,QAAQ,MAAc,IAAI,OAAO,MAAM,sBAAsB,aAAa,GAAG;AAmBnF,UAAU,SAAS,SAA6C;AACrE,QAAM,UAAU,QAAQ,SAAS,MAAM,CAAC;AAExC,aAAW,SAAS,SAAS;AAC3B,QAAI;AACF,YAAM,CAAC,WAAW,IAAI,IAAI;AAE1B,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,OAAO,MAAM;AAAA,QACb,KAAK,MAAM,QAAS,UAAU;AAAA,MAChC;AAAA,IACF,SAAS,IAAP;AAAA,IAEF;AAAA,EACF;AACF;AAGO,SAAS,WAAW,SAAiB,UAAkD;AAC5F,SAAO,QAAQ,WAAW,MAAM,GAAG,CAAC,WAAW,SAAS;AACtD,WAAO,SAAS;AAAA,MACd;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;",
|
||||
"names": []
|
||||
}
|
||||
42
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip39.js
generated
vendored
Normal file
42
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip39.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip39.ts
|
||||
var nip39_exports = {};
|
||||
__export(nip39_exports, {
|
||||
useFetchImplementation: () => useFetchImplementation,
|
||||
validateGithub: () => validateGithub
|
||||
});
|
||||
module.exports = __toCommonJS(nip39_exports);
|
||||
var _fetch;
|
||||
try {
|
||||
_fetch = fetch;
|
||||
} catch {
|
||||
}
|
||||
function useFetchImplementation(fetchImplementation) {
|
||||
_fetch = fetchImplementation;
|
||||
}
|
||||
async function validateGithub(pubkey, username, proof) {
|
||||
try {
|
||||
let res = await (await _fetch(`https://gist.github.com/${username}/${proof}/raw`)).text();
|
||||
return res === `Verifying that I control the following Nostr public key: ${pubkey}`;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip39.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip39.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip39.ts"],
|
||||
"sourcesContent": ["var _fetch: any\n\ntry {\n _fetch = fetch\n} catch {}\n\nexport function useFetchImplementation(fetchImplementation: any) {\n _fetch = fetchImplementation\n}\n\nexport async function validateGithub(pubkey: string, username: string, proof: string): Promise<boolean> {\n try {\n let res = await (await _fetch(`https://gist.github.com/${username}/${proof}/raw`)).text()\n return res === `Verifying that I control the following Nostr public key: ${pubkey}`\n } catch (_) {\n return false\n }\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAI;AAEJ,IAAI;AACF,WAAS;AACX,QAAE;AAAO;AAEF,SAAS,uBAAuB,qBAA0B;AAC/D,WAAS;AACX;AAEA,eAAsB,eAAe,QAAgB,UAAkB,OAAiC;AACtG,MAAI;AACF,QAAI,MAAM,OAAO,MAAM,OAAO,2BAA2B,YAAY,WAAW,GAAG,KAAK;AACxF,WAAO,QAAQ,4DAA4D;AAAA,EAC7E,SAAS,GAAP;AACA,WAAO;AAAA,EACT;AACF;",
|
||||
"names": []
|
||||
}
|
||||
63
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip40.js
generated
vendored
Normal file
63
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip40.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip40.ts
|
||||
var nip40_exports = {};
|
||||
__export(nip40_exports, {
|
||||
getExpiration: () => getExpiration,
|
||||
isEventExpired: () => isEventExpired,
|
||||
onExpire: () => onExpire,
|
||||
waitForExpire: () => waitForExpire
|
||||
});
|
||||
module.exports = __toCommonJS(nip40_exports);
|
||||
function getExpiration(event) {
|
||||
const tag = event.tags.find(([name]) => name === "expiration");
|
||||
if (tag) {
|
||||
return new Date(parseInt(tag[1]) * 1e3);
|
||||
}
|
||||
}
|
||||
function isEventExpired(event) {
|
||||
const expiration = getExpiration(event);
|
||||
if (expiration) {
|
||||
return Date.now() > expiration.getTime();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function waitForExpire(event) {
|
||||
const expiration = getExpiration(event);
|
||||
if (expiration) {
|
||||
const diff = expiration.getTime() - Date.now();
|
||||
if (diff > 0) {
|
||||
await sleep(diff);
|
||||
return event;
|
||||
} else {
|
||||
return event;
|
||||
}
|
||||
} else {
|
||||
throw new Error("Event has no expiration");
|
||||
}
|
||||
}
|
||||
function onExpire(event, callback) {
|
||||
waitForExpire(event).then(callback).catch(() => {
|
||||
});
|
||||
}
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip40.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip40.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip40.ts"],
|
||||
"sourcesContent": ["import { Event } from './core.ts'\n\n/** Get the expiration of the event as a `Date` object, if any. */\nfunction getExpiration(event: Event): Date | undefined {\n const tag = event.tags.find(([name]) => name === 'expiration')\n if (tag) {\n return new Date(parseInt(tag[1]) * 1000)\n }\n}\n\n/** Check if the event has expired. */\nfunction isEventExpired(event: Event): boolean {\n const expiration = getExpiration(event)\n if (expiration) {\n return Date.now() > expiration.getTime()\n } else {\n return false\n }\n}\n\n/** Returns a promise that resolves when the event expires. */\nasync function waitForExpire(event: Event): Promise<Event> {\n const expiration = getExpiration(event)\n if (expiration) {\n const diff = expiration.getTime() - Date.now()\n if (diff > 0) {\n await sleep(diff)\n return event\n } else {\n return event\n }\n } else {\n throw new Error('Event has no expiration')\n }\n}\n\n/** Calls the callback when the event expires. */\nfunction onExpire(event: Event, callback: (event: Event) => void): void {\n waitForExpire(event)\n .then(callback)\n .catch(() => {})\n}\n\n/** Resolves when the given number of milliseconds have elapsed. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nexport { getExpiration, isEventExpired, waitForExpire, onExpire }\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,SAAS,cAAc,OAAgC;AACrD,QAAM,MAAM,MAAM,KAAK,KAAK,CAAC,CAAC,IAAI,MAAM,SAAS,YAAY;AAC7D,MAAI,KAAK;AACP,WAAO,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,GAAI;AAAA,EACzC;AACF;AAGA,SAAS,eAAe,OAAuB;AAC7C,QAAM,aAAa,cAAc,KAAK;AACtC,MAAI,YAAY;AACd,WAAO,KAAK,IAAI,IAAI,WAAW,QAAQ;AAAA,EACzC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAGA,eAAe,cAAc,OAA8B;AACzD,QAAM,aAAa,cAAc,KAAK;AACtC,MAAI,YAAY;AACd,UAAM,OAAO,WAAW,QAAQ,IAAI,KAAK,IAAI;AAC7C,QAAI,OAAO,GAAG;AACZ,YAAM,MAAM,IAAI;AAChB,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AACL,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACF;AAGA,SAAS,SAAS,OAAc,UAAwC;AACtE,gBAAc,KAAK,EAChB,KAAK,QAAQ,EACb,MAAM,MAAM;AAAA,EAAC,CAAC;AACnB;AAGA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AACvD;",
|
||||
"names": []
|
||||
}
|
||||
41
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip42.js
generated
vendored
Normal file
41
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip42.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip42.ts
|
||||
var nip42_exports = {};
|
||||
__export(nip42_exports, {
|
||||
makeAuthEvent: () => makeAuthEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip42_exports);
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip42.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip42.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
143
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip44.js
generated
vendored
Normal file
143
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip44.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip44.ts
|
||||
var nip44_exports = {};
|
||||
__export(nip44_exports, {
|
||||
decrypt: () => decrypt,
|
||||
encrypt: () => encrypt,
|
||||
getConversationKey: () => getConversationKey,
|
||||
v2: () => v2
|
||||
});
|
||||
module.exports = __toCommonJS(nip44_exports);
|
||||
var import_chacha = require("@noble/ciphers/chacha");
|
||||
var import_utils2 = require("@noble/ciphers/utils");
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_hkdf = require("@noble/hashes/hkdf");
|
||||
var import_hmac = require("@noble/hashes/hmac");
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
var import_utils3 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip44.ts
|
||||
var minPlaintextSize = 1;
|
||||
var maxPlaintextSize = 65535;
|
||||
function getConversationKey(privkeyA, pubkeyB) {
|
||||
const sharedX = import_secp256k1.secp256k1.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
|
||||
return (0, import_hkdf.extract)(import_sha256.sha256, sharedX, "nip44-v2");
|
||||
}
|
||||
function getMessageKeys(conversationKey, nonce) {
|
||||
const keys = (0, import_hkdf.expand)(import_sha256.sha256, conversationKey, nonce, 76);
|
||||
return {
|
||||
chacha_key: keys.subarray(0, 32),
|
||||
chacha_nonce: keys.subarray(32, 44),
|
||||
hmac_key: keys.subarray(44, 76)
|
||||
};
|
||||
}
|
||||
function calcPaddedLen(len) {
|
||||
if (!Number.isSafeInteger(len) || len < 1)
|
||||
throw new Error("expected positive integer");
|
||||
if (len <= 32)
|
||||
return 32;
|
||||
const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;
|
||||
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
|
||||
return chunk * (Math.floor((len - 1) / chunk) + 1);
|
||||
}
|
||||
function writeU16BE(num) {
|
||||
if (!Number.isSafeInteger(num) || num < minPlaintextSize || num > maxPlaintextSize)
|
||||
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
|
||||
const arr = new Uint8Array(2);
|
||||
new DataView(arr.buffer).setUint16(0, num, false);
|
||||
return arr;
|
||||
}
|
||||
function pad(plaintext) {
|
||||
const unpadded = utf8Encoder.encode(plaintext);
|
||||
const unpaddedLen = unpadded.length;
|
||||
const prefix = writeU16BE(unpaddedLen);
|
||||
const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen);
|
||||
return (0, import_utils3.concatBytes)(prefix, unpadded, suffix);
|
||||
}
|
||||
function unpad(padded) {
|
||||
const unpaddedLen = new DataView(padded.buffer).getUint16(0);
|
||||
const unpadded = padded.subarray(2, 2 + unpaddedLen);
|
||||
if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + calcPaddedLen(unpaddedLen))
|
||||
throw new Error("invalid padding");
|
||||
return utf8Decoder.decode(unpadded);
|
||||
}
|
||||
function hmacAad(key, message, aad) {
|
||||
if (aad.length !== 32)
|
||||
throw new Error("AAD associated data must be 32 bytes");
|
||||
const combined = (0, import_utils3.concatBytes)(aad, message);
|
||||
return (0, import_hmac.hmac)(import_sha256.sha256, key, combined);
|
||||
}
|
||||
function decodePayload(payload) {
|
||||
if (typeof payload !== "string")
|
||||
throw new Error("payload must be a valid string");
|
||||
const plen = payload.length;
|
||||
if (plen < 132 || plen > 87472)
|
||||
throw new Error("invalid payload length: " + plen);
|
||||
if (payload[0] === "#")
|
||||
throw new Error("unknown encryption version");
|
||||
let data;
|
||||
try {
|
||||
data = import_base.base64.decode(payload);
|
||||
} catch (error) {
|
||||
throw new Error("invalid base64: " + error.message);
|
||||
}
|
||||
const dlen = data.length;
|
||||
if (dlen < 99 || dlen > 65603)
|
||||
throw new Error("invalid data length: " + dlen);
|
||||
const vers = data[0];
|
||||
if (vers !== 2)
|
||||
throw new Error("unknown encryption version " + vers);
|
||||
return {
|
||||
nonce: data.subarray(1, 33),
|
||||
ciphertext: data.subarray(33, -32),
|
||||
mac: data.subarray(-32)
|
||||
};
|
||||
}
|
||||
function encrypt(plaintext, conversationKey, nonce = (0, import_utils3.randomBytes)(32)) {
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const padded = pad(plaintext);
|
||||
const ciphertext = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, padded);
|
||||
const mac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
return import_base.base64.encode((0, import_utils3.concatBytes)(new Uint8Array([2]), nonce, ciphertext, mac));
|
||||
}
|
||||
function decrypt(payload, conversationKey) {
|
||||
const { nonce, ciphertext, mac } = decodePayload(payload);
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const calculatedMac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
if (!(0, import_utils2.equalBytes)(calculatedMac, mac))
|
||||
throw new Error("invalid MAC");
|
||||
const padded = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, ciphertext);
|
||||
return unpad(padded);
|
||||
}
|
||||
var v2 = {
|
||||
utils: {
|
||||
getConversationKey,
|
||||
calcPaddedLen
|
||||
},
|
||||
encrypt,
|
||||
decrypt
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip44.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip44.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1360
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip46.js
generated
vendored
Normal file
1360
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip46.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip46.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip46.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
168
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip47.js
generated
vendored
Normal file
168
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip47.js
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip47.ts
|
||||
var nip47_exports = {};
|
||||
__export(nip47_exports, {
|
||||
makeNwcRequestEvent: () => makeNwcRequestEvent,
|
||||
parseConnectionString: () => parseConnectionString
|
||||
});
|
||||
module.exports = __toCommonJS(nip47_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var NWCWalletRequest = 23194;
|
||||
|
||||
// nip04.ts
|
||||
var import_utils4 = require("@noble/hashes/utils");
|
||||
var import_secp256k12 = require("@noble/curves/secp256k1");
|
||||
var import_aes = require("@noble/ciphers/aes");
|
||||
var import_base = require("@scure/base");
|
||||
function encrypt(secretKey, pubkey, text) {
|
||||
const privkey = secretKey instanceof Uint8Array ? (0, import_utils4.bytesToHex)(secretKey) : secretKey;
|
||||
const key = import_secp256k12.secp256k1.getSharedSecret(privkey, "02" + pubkey);
|
||||
const normalizedKey = getNormalizedX(key);
|
||||
let iv = Uint8Array.from((0, import_utils4.randomBytes)(16));
|
||||
let plaintext = utf8Encoder.encode(text);
|
||||
let ciphertext = (0, import_aes.cbc)(normalizedKey, iv).encrypt(plaintext);
|
||||
let ctb64 = import_base.base64.encode(new Uint8Array(ciphertext));
|
||||
let ivb64 = import_base.base64.encode(new Uint8Array(iv.buffer));
|
||||
return `${ctb64}?iv=${ivb64}`;
|
||||
}
|
||||
function getNormalizedX(key) {
|
||||
return key.slice(1, 33);
|
||||
}
|
||||
|
||||
// nip47.ts
|
||||
function parseConnectionString(connectionString) {
|
||||
const { host, pathname, searchParams } = new URL(connectionString);
|
||||
const pubkey = pathname || host;
|
||||
const relay = searchParams.get("relay");
|
||||
const secret = searchParams.get("secret");
|
||||
if (!pubkey || !relay || !secret) {
|
||||
throw new Error("invalid connection string");
|
||||
}
|
||||
return { pubkey, relay, secret };
|
||||
}
|
||||
async function makeNwcRequestEvent(pubkey, secretKey, invoice) {
|
||||
const content = {
|
||||
method: "pay_invoice",
|
||||
params: {
|
||||
invoice
|
||||
}
|
||||
};
|
||||
const encryptedContent = encrypt(secretKey, pubkey, JSON.stringify(content));
|
||||
const eventTemplate = {
|
||||
kind: NWCWalletRequest,
|
||||
created_at: Math.round(Date.now() / 1e3),
|
||||
content: encryptedContent,
|
||||
tags: [["p", pubkey]]
|
||||
};
|
||||
return finalizeEvent(eventTemplate, secretKey);
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip47.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip47.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
77
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip49.js
generated
vendored
Normal file
77
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip49.js
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip49.ts
|
||||
var nip49_exports = {};
|
||||
__export(nip49_exports, {
|
||||
decrypt: () => decrypt,
|
||||
encrypt: () => encrypt
|
||||
});
|
||||
module.exports = __toCommonJS(nip49_exports);
|
||||
var import_scrypt = require("@noble/hashes/scrypt");
|
||||
var import_chacha = require("@noble/ciphers/chacha");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// nip19.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
var Bech32MaxSize = 5e3;
|
||||
function encodeBech32(prefix, data) {
|
||||
let words = import_base.bech32.toWords(data);
|
||||
return import_base.bech32.encode(prefix, words, Bech32MaxSize);
|
||||
}
|
||||
function encodeBytes(prefix, bytes) {
|
||||
return encodeBech32(prefix, bytes);
|
||||
}
|
||||
|
||||
// nip49.ts
|
||||
var import_base2 = require("@scure/base");
|
||||
function encrypt(sec, password, logn = 16, ksb = 2) {
|
||||
let salt = (0, import_utils2.randomBytes)(16);
|
||||
let n = 2 ** logn;
|
||||
let key = (0, import_scrypt.scrypt)(password.normalize("NFKC"), salt, { N: n, r: 8, p: 1, dkLen: 32 });
|
||||
let nonce = (0, import_utils2.randomBytes)(24);
|
||||
let aad = Uint8Array.from([ksb]);
|
||||
let xc2p1 = (0, import_chacha.xchacha20poly1305)(key, nonce, aad);
|
||||
let ciphertext = xc2p1.encrypt(sec);
|
||||
let b = (0, import_utils2.concatBytes)(Uint8Array.from([2]), Uint8Array.from([logn]), salt, nonce, aad, ciphertext);
|
||||
return encodeBytes("ncryptsec", b);
|
||||
}
|
||||
function decrypt(ncryptsec, password) {
|
||||
let { prefix, words } = import_base2.bech32.decode(ncryptsec, Bech32MaxSize);
|
||||
if (prefix !== "ncryptsec") {
|
||||
throw new Error(`invalid prefix ${prefix}, expected 'ncryptsec'`);
|
||||
}
|
||||
let b = new Uint8Array(import_base2.bech32.fromWords(words));
|
||||
let version = b[0];
|
||||
if (version !== 2) {
|
||||
throw new Error(`invalid version ${version}, expected 0x02`);
|
||||
}
|
||||
let logn = b[1];
|
||||
let n = 2 ** logn;
|
||||
let salt = b.slice(2, 2 + 16);
|
||||
let nonce = b.slice(2 + 16, 2 + 16 + 24);
|
||||
let ksb = b[2 + 16 + 24];
|
||||
let aad = Uint8Array.from([ksb]);
|
||||
let ciphertext = b.slice(2 + 16 + 24 + 1);
|
||||
let key = (0, import_scrypt.scrypt)(password.normalize("NFKC"), salt, { N: n, r: 8, p: 1, dkLen: 32 });
|
||||
let xc2p1 = (0, import_chacha.xchacha20poly1305)(key, nonce, aad);
|
||||
let sec = xc2p1.decrypt(ciphertext);
|
||||
return sec;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip49.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip49.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
35
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip54.js
generated
vendored
Normal file
35
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip54.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip54.ts
|
||||
var nip54_exports = {};
|
||||
__export(nip54_exports, {
|
||||
normalizeIdentifier: () => normalizeIdentifier
|
||||
});
|
||||
module.exports = __toCommonJS(nip54_exports);
|
||||
function normalizeIdentifier(name) {
|
||||
name = name.trim().toLowerCase();
|
||||
name = name.normalize("NFKC");
|
||||
return Array.from(name).map((char) => {
|
||||
if (/\p{Letter}/u.test(char) || /\p{Number}/u.test(char)) {
|
||||
return char;
|
||||
}
|
||||
return "-";
|
||||
}).join("");
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip54.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip54.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip54.ts"],
|
||||
"sourcesContent": ["export function normalizeIdentifier(name: string): string {\n // Trim and lowercase\n name = name.trim().toLowerCase()\n\n // Normalize Unicode to NFKC form\n name = name.normalize('NFKC')\n\n // Convert to array of characters and map each one\n return Array.from(name)\n .map(char => {\n // Check if character is letter or number using Unicode ranges\n if (/\\p{Letter}/u.test(char) || /\\p{Number}/u.test(char)) {\n return char\n }\n\n return '-'\n })\n .join('')\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,oBAAoB,MAAsB;AAExD,SAAO,KAAK,KAAK,EAAE,YAAY;AAG/B,SAAO,KAAK,UAAU,MAAM;AAG5B,SAAO,MAAM,KAAK,IAAI,EACnB,IAAI,UAAQ;AAEX,QAAI,cAAc,KAAK,IAAI,KAAK,cAAc,KAAK,IAAI,GAAG;AACxD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC,EACA,KAAK,EAAE;AACZ;",
|
||||
"names": []
|
||||
}
|
||||
103
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip55.js
generated
vendored
Normal file
103
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip55.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip55.ts
|
||||
var nip55_exports = {};
|
||||
__export(nip55_exports, {
|
||||
decryptNip04Uri: () => decryptNip04Uri,
|
||||
decryptNip44Uri: () => decryptNip44Uri,
|
||||
decryptZapEventUri: () => decryptZapEventUri,
|
||||
encryptNip04Uri: () => encryptNip04Uri,
|
||||
encryptNip44Uri: () => encryptNip44Uri,
|
||||
getPublicKeyUri: () => getPublicKeyUri,
|
||||
signEventUri: () => signEventUri
|
||||
});
|
||||
module.exports = __toCommonJS(nip55_exports);
|
||||
function encodeParams(params) {
|
||||
return new URLSearchParams(params).toString();
|
||||
}
|
||||
function filterUndefined(obj) {
|
||||
return Object.fromEntries(Object.entries(obj).filter(([, value]) => value !== void 0));
|
||||
}
|
||||
function buildUri({
|
||||
base,
|
||||
type,
|
||||
callbackUrl,
|
||||
returnType = "signature",
|
||||
compressionType = "none",
|
||||
...params
|
||||
}) {
|
||||
const baseParams = {
|
||||
type,
|
||||
compressionType,
|
||||
returnType,
|
||||
callbackUrl,
|
||||
id: params.id,
|
||||
current_user: params.currentUser,
|
||||
permissions: params.permissions && params.permissions.length > 0 ? encodeURIComponent(JSON.stringify(params.permissions)) : void 0,
|
||||
pubKey: params.pubKey,
|
||||
plainText: params.plainText,
|
||||
encryptedText: params.encryptedText,
|
||||
appName: params.appName
|
||||
};
|
||||
const filteredParams = filterUndefined(baseParams);
|
||||
return `${base}?${encodeParams(filteredParams)}`;
|
||||
}
|
||||
function buildDefaultUri(type, params) {
|
||||
return buildUri({
|
||||
base: "nostrsigner:",
|
||||
type,
|
||||
...params
|
||||
});
|
||||
}
|
||||
function getPublicKeyUri({ permissions = [], ...params }) {
|
||||
return buildDefaultUri("get_public_key", { permissions, ...params });
|
||||
}
|
||||
function signEventUri({ eventJson, ...params }) {
|
||||
return buildUri({
|
||||
base: `nostrsigner:${encodeURIComponent(JSON.stringify(eventJson))}`,
|
||||
type: "sign_event",
|
||||
...params
|
||||
});
|
||||
}
|
||||
function encryptUri(type, params) {
|
||||
return buildDefaultUri(type, { ...params, plainText: params.content });
|
||||
}
|
||||
function decryptUri(type, params) {
|
||||
return buildDefaultUri(type, { ...params, encryptedText: params.content });
|
||||
}
|
||||
function encryptNip04Uri(params) {
|
||||
return encryptUri("nip04_encrypt", params);
|
||||
}
|
||||
function decryptNip04Uri(params) {
|
||||
return decryptUri("nip04_decrypt", params);
|
||||
}
|
||||
function encryptNip44Uri(params) {
|
||||
return encryptUri("nip44_encrypt", params);
|
||||
}
|
||||
function decryptNip44Uri(params) {
|
||||
return decryptUri("nip44_decrypt", params);
|
||||
}
|
||||
function decryptZapEventUri({ eventJson, ...params }) {
|
||||
return buildUri({
|
||||
base: `nostrsigner:${encodeURIComponent(JSON.stringify(eventJson))}`,
|
||||
type: "decrypt_zap_event",
|
||||
...params
|
||||
});
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip55.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip55.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../nip55.ts"],
|
||||
"sourcesContent": ["type BaseParams = {\n callbackUrl?: string\n returnType?: 'signature' | 'event'\n compressionType?: 'none' | 'gzip'\n}\n\ntype PermissionsParams = BaseParams & {\n permissions?: { type: string; kind?: number }[]\n}\n\ntype EventUriParams = BaseParams & {\n eventJson: Record<string, unknown>\n id?: string\n currentUser?: string\n}\n\ntype EncryptDecryptParams = BaseParams & {\n pubKey: string\n content: string\n id?: string\n currentUser?: string\n}\n\ntype UriParams = BaseParams & {\n base: string\n type: string\n id?: string\n currentUser?: string\n permissions?: { type: string; kind?: number }[]\n pubKey?: string\n plainText?: string\n encryptedText?: string\n appName?: string\n}\n\nfunction encodeParams(params: Record<string, unknown>): string {\n return new URLSearchParams(params as Record<string, string>).toString()\n}\n\nfunction filterUndefined<T extends Record<string, unknown>>(obj: T): T {\n return Object.fromEntries(Object.entries(obj).filter(([, value]) => value !== undefined)) as T\n}\n\nfunction buildUri({\n base,\n type,\n callbackUrl,\n returnType = 'signature',\n compressionType = 'none',\n ...params\n}: UriParams): string {\n const baseParams = {\n type,\n compressionType,\n returnType,\n callbackUrl,\n id: params.id,\n current_user: params.currentUser,\n permissions:\n params.permissions && params.permissions.length > 0\n ? encodeURIComponent(JSON.stringify(params.permissions))\n : undefined,\n pubKey: params.pubKey,\n plainText: params.plainText,\n encryptedText: params.encryptedText,\n appName: params.appName,\n }\n\n const filteredParams = filterUndefined(baseParams)\n return `${base}?${encodeParams(filteredParams)}`\n}\n\nfunction buildDefaultUri(type: string, params: Partial<UriParams>): string {\n return buildUri({\n base: 'nostrsigner:',\n type,\n ...params,\n })\n}\n\nexport function getPublicKeyUri({ permissions = [], ...params }: PermissionsParams): string {\n return buildDefaultUri('get_public_key', { permissions, ...params })\n}\n\nexport function signEventUri({ eventJson, ...params }: EventUriParams): string {\n return buildUri({\n base: `nostrsigner:${encodeURIComponent(JSON.stringify(eventJson))}`,\n type: 'sign_event',\n ...params,\n })\n}\n\nfunction encryptUri(type: 'nip44_encrypt' | 'nip04_encrypt', params: EncryptDecryptParams): string {\n return buildDefaultUri(type, { ...params, plainText: params.content })\n}\n\nfunction decryptUri(type: 'nip44_decrypt' | 'nip04_decrypt', params: EncryptDecryptParams): string {\n return buildDefaultUri(type, { ...params, encryptedText: params.content })\n}\n\nexport function encryptNip04Uri(params: EncryptDecryptParams): string {\n return encryptUri('nip04_encrypt', params)\n}\n\nexport function decryptNip04Uri(params: EncryptDecryptParams): string {\n return decryptUri('nip04_decrypt', params)\n}\n\nexport function encryptNip44Uri(params: EncryptDecryptParams): string {\n return encryptUri('nip44_encrypt', params)\n}\n\nexport function decryptNip44Uri(params: EncryptDecryptParams): string {\n return decryptUri('nip44_decrypt', params)\n}\n\nexport function decryptZapEventUri({ eventJson, ...params }: EventUriParams): string {\n return buildUri({\n base: `nostrsigner:${encodeURIComponent(JSON.stringify(eventJson))}`,\n type: 'decrypt_zap_event',\n ...params,\n })\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCA,SAAS,aAAa,QAAyC;AAC7D,SAAO,IAAI,gBAAgB,MAAgC,EAAE,SAAS;AACxE;AAEA,SAAS,gBAAmD,KAAW;AACrE,SAAO,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS,CAAC;AAC1F;AAEA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,kBAAkB;AAAA,KACf;AACL,GAAsB;AACpB,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,OAAO;AAAA,IACX,cAAc,OAAO;AAAA,IACrB,aACE,OAAO,eAAe,OAAO,YAAY,SAAS,IAC9C,mBAAmB,KAAK,UAAU,OAAO,WAAW,CAAC,IACrD;AAAA,IACN,QAAQ,OAAO;AAAA,IACf,WAAW,OAAO;AAAA,IAClB,eAAe,OAAO;AAAA,IACtB,SAAS,OAAO;AAAA,EAClB;AAEA,QAAM,iBAAiB,gBAAgB,UAAU;AACjD,SAAO,GAAG,QAAQ,aAAa,cAAc;AAC/C;AAEA,SAAS,gBAAgB,MAAc,QAAoC;AACzE,SAAO,SAAS;AAAA,IACd,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACL,CAAC;AACH;AAEO,SAAS,gBAAgB,EAAE,cAAc,CAAC,MAAM,OAAO,GAA8B;AAC1F,SAAO,gBAAgB,kBAAkB,EAAE,aAAa,GAAG,OAAO,CAAC;AACrE;AAEO,SAAS,aAAa,EAAE,cAAc,OAAO,GAA2B;AAC7E,SAAO,SAAS;AAAA,IACd,MAAM,eAAe,mBAAmB,KAAK,UAAU,SAAS,CAAC;AAAA,IACjE,MAAM;AAAA,IACN,GAAG;AAAA,EACL,CAAC;AACH;AAEA,SAAS,WAAW,MAAyC,QAAsC;AACjG,SAAO,gBAAgB,MAAM,EAAE,GAAG,QAAQ,WAAW,OAAO,QAAQ,CAAC;AACvE;AAEA,SAAS,WAAW,MAAyC,QAAsC;AACjG,SAAO,gBAAgB,MAAM,EAAE,GAAG,QAAQ,eAAe,OAAO,QAAQ,CAAC;AAC3E;AAEO,SAAS,gBAAgB,QAAsC;AACpE,SAAO,WAAW,iBAAiB,MAAM;AAC3C;AAEO,SAAS,gBAAgB,QAAsC;AACpE,SAAO,WAAW,iBAAiB,MAAM;AAC3C;AAEO,SAAS,gBAAgB,QAAsC;AACpE,SAAO,WAAW,iBAAiB,MAAM;AAC3C;AAEO,SAAS,gBAAgB,QAAsC;AACpE,SAAO,WAAW,iBAAiB,MAAM;AAC3C;AAEO,SAAS,mBAAmB,EAAE,cAAc,OAAO,GAA2B;AACnF,SAAO,SAAS;AAAA,IACd,MAAM,eAAe,mBAAmB,KAAK,UAAU,SAAS,CAAC;AAAA,IACjE,MAAM;AAAA,IACN,GAAG;AAAA,EACL,CAAC;AACH;",
|
||||
"names": []
|
||||
}
|
||||
274
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip57.js
generated
vendored
Normal file
274
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip57.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip57.ts
|
||||
var nip57_exports = {};
|
||||
__export(nip57_exports, {
|
||||
getSatoshisAmountFromBolt11: () => getSatoshisAmountFromBolt11,
|
||||
getZapEndpoint: () => getZapEndpoint,
|
||||
makeZapReceipt: () => makeZapReceipt,
|
||||
makeZapRequest: () => makeZapRequest,
|
||||
useFetchImplementation: () => useFetchImplementation,
|
||||
validateZapRequest: () => validateZapRequest
|
||||
});
|
||||
module.exports = __toCommonJS(nip57_exports);
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
function isReplaceableKind(kind) {
|
||||
return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;
|
||||
}
|
||||
function isAddressableKind(kind) {
|
||||
return 3e4 <= kind && kind < 4e4;
|
||||
}
|
||||
|
||||
// nip57.ts
|
||||
var _fetch;
|
||||
try {
|
||||
_fetch = fetch;
|
||||
} catch {
|
||||
}
|
||||
function useFetchImplementation(fetchImplementation) {
|
||||
_fetch = fetchImplementation;
|
||||
}
|
||||
async function getZapEndpoint(metadata) {
|
||||
try {
|
||||
let lnurl = "";
|
||||
let { lud06, lud16 } = JSON.parse(metadata.content);
|
||||
if (lud06) {
|
||||
let { words } = import_base.bech32.decode(lud06, 1e3);
|
||||
let data = import_base.bech32.fromWords(words);
|
||||
lnurl = utf8Decoder.decode(data);
|
||||
} else if (lud16) {
|
||||
let [name, domain] = lud16.split("@");
|
||||
lnurl = new URL(`/.well-known/lnurlp/${name}`, `https://${domain}`).toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
let res = await _fetch(lnurl);
|
||||
let body = await res.json();
|
||||
if (body.allowsNostr && body.nostrPubkey) {
|
||||
return body.callback;
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function makeZapRequest(params) {
|
||||
let zr = {
|
||||
kind: 9734,
|
||||
created_at: Math.round(Date.now() / 1e3),
|
||||
content: params.comment || "",
|
||||
tags: [
|
||||
["p", "pubkey" in params ? params.pubkey : params.event.pubkey],
|
||||
["amount", params.amount.toString()],
|
||||
["relays", ...params.relays]
|
||||
]
|
||||
};
|
||||
if ("event" in params) {
|
||||
zr.tags.push(["e", params.event.id]);
|
||||
if (isReplaceableKind(params.event.kind)) {
|
||||
const a = ["a", `${params.event.kind}:${params.event.pubkey}:`];
|
||||
zr.tags.push(a);
|
||||
} else if (isAddressableKind(params.event.kind)) {
|
||||
let d = params.event.tags.find(([t, v]) => t === "d" && v);
|
||||
if (!d)
|
||||
throw new Error("d tag not found or is empty");
|
||||
const a = ["a", `${params.event.kind}:${params.event.pubkey}:${d[1]}`];
|
||||
zr.tags.push(a);
|
||||
}
|
||||
zr.tags.push(["k", params.event.kind.toString()]);
|
||||
}
|
||||
return zr;
|
||||
}
|
||||
function validateZapRequest(zapRequestString) {
|
||||
let zapRequest;
|
||||
try {
|
||||
zapRequest = JSON.parse(zapRequestString);
|
||||
} catch (err) {
|
||||
return "Invalid zap request JSON.";
|
||||
}
|
||||
if (!validateEvent(zapRequest))
|
||||
return "Zap request is not a valid Nostr event.";
|
||||
if (!verifyEvent(zapRequest))
|
||||
return "Invalid signature on zap request.";
|
||||
let p = zapRequest.tags.find(([t, v]) => t === "p" && v);
|
||||
if (!p)
|
||||
return "Zap request doesn't have a 'p' tag.";
|
||||
if (!p[1].match(/^[a-f0-9]{64}$/))
|
||||
return "Zap request 'p' tag is not valid hex.";
|
||||
let e = zapRequest.tags.find(([t, v]) => t === "e" && v);
|
||||
if (e && !e[1].match(/^[a-f0-9]{64}$/))
|
||||
return "Zap request 'e' tag is not valid hex.";
|
||||
let relays = zapRequest.tags.find(([t, v]) => t === "relays" && v);
|
||||
if (!relays)
|
||||
return "Zap request doesn't have a 'relays' tag.";
|
||||
return null;
|
||||
}
|
||||
function makeZapReceipt({
|
||||
zapRequest,
|
||||
preimage,
|
||||
bolt11,
|
||||
paidAt
|
||||
}) {
|
||||
let zr = JSON.parse(zapRequest);
|
||||
let tagsFromZapRequest = zr.tags.filter(([t]) => t === "e" || t === "p" || t === "a");
|
||||
let zap = {
|
||||
kind: 9735,
|
||||
created_at: Math.round(paidAt.getTime() / 1e3),
|
||||
content: "",
|
||||
tags: [...tagsFromZapRequest, ["P", zr.pubkey], ["bolt11", bolt11], ["description", zapRequest]]
|
||||
};
|
||||
if (preimage) {
|
||||
zap.tags.push(["preimage", preimage]);
|
||||
}
|
||||
return zap;
|
||||
}
|
||||
function getSatoshisAmountFromBolt11(bolt11) {
|
||||
if (bolt11.length < 50) {
|
||||
return 0;
|
||||
}
|
||||
bolt11 = bolt11.substring(0, 50);
|
||||
const idx = bolt11.lastIndexOf("1");
|
||||
if (idx === -1) {
|
||||
return 0;
|
||||
}
|
||||
const hrp = bolt11.substring(0, idx);
|
||||
if (!hrp.startsWith("lnbc")) {
|
||||
return 0;
|
||||
}
|
||||
const amount = hrp.substring(4);
|
||||
if (amount.length < 1) {
|
||||
return 0;
|
||||
}
|
||||
const char = amount[amount.length - 1];
|
||||
const digit = char.charCodeAt(0) - "0".charCodeAt(0);
|
||||
const isDigit = digit >= 0 && digit <= 9;
|
||||
let cutPoint = amount.length - 1;
|
||||
if (isDigit) {
|
||||
cutPoint++;
|
||||
}
|
||||
if (cutPoint < 1) {
|
||||
return 0;
|
||||
}
|
||||
const num = parseInt(amount.substring(0, cutPoint));
|
||||
switch (char) {
|
||||
case "m":
|
||||
return num * 1e5;
|
||||
case "u":
|
||||
return num * 100;
|
||||
case "n":
|
||||
return num / 10;
|
||||
case "p":
|
||||
return num / 1e4;
|
||||
default:
|
||||
return num * 1e8;
|
||||
}
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip57.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip57.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
117
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip58.js
generated
vendored
Normal file
117
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip58.js
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip58.ts
|
||||
var nip58_exports = {};
|
||||
__export(nip58_exports, {
|
||||
generateBadgeAwardEventTemplate: () => generateBadgeAwardEventTemplate,
|
||||
generateBadgeDefinitionEventTemplate: () => generateBadgeDefinitionEventTemplate,
|
||||
generateProfileBadgesEventTemplate: () => generateProfileBadgesEventTemplate,
|
||||
validateBadgeAwardEvent: () => validateBadgeAwardEvent,
|
||||
validateBadgeDefinitionEvent: () => validateBadgeDefinitionEvent,
|
||||
validateProfileBadgesEvent: () => validateProfileBadgesEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip58_exports);
|
||||
|
||||
// kinds.ts
|
||||
var BadgeAward = 8;
|
||||
var ProfileBadges = 30008;
|
||||
var BadgeDefinition = 30009;
|
||||
|
||||
// nip58.ts
|
||||
function generateBadgeDefinitionEventTemplate({
|
||||
d,
|
||||
description,
|
||||
image,
|
||||
name,
|
||||
thumbs
|
||||
}) {
|
||||
const tags = [["d", d]];
|
||||
name && tags.push(["name", name]);
|
||||
description && tags.push(["description", description]);
|
||||
image && tags.push(["image", ...image]);
|
||||
if (thumbs) {
|
||||
for (const thumb of thumbs) {
|
||||
tags.push(["thumb", ...thumb]);
|
||||
}
|
||||
}
|
||||
const eventTemplate = {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: BadgeDefinition,
|
||||
tags
|
||||
};
|
||||
return eventTemplate;
|
||||
}
|
||||
function validateBadgeDefinitionEvent(event) {
|
||||
if (event.kind !== BadgeDefinition)
|
||||
return false;
|
||||
const requiredTags = ["d"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function generateBadgeAwardEventTemplate({ a, p }) {
|
||||
const tags = [["a", a]];
|
||||
for (const _p of p) {
|
||||
tags.push(["p", ..._p]);
|
||||
}
|
||||
const eventTemplate = {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: BadgeAward,
|
||||
tags
|
||||
};
|
||||
return eventTemplate;
|
||||
}
|
||||
function validateBadgeAwardEvent(event) {
|
||||
if (event.kind !== BadgeAward)
|
||||
return false;
|
||||
const requiredTags = ["a", "p"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function generateProfileBadgesEventTemplate({ badges }) {
|
||||
const tags = [["d", "profile_badges"]];
|
||||
for (const badge of badges) {
|
||||
tags.push(["a", badge.a], ["e", ...badge.e]);
|
||||
}
|
||||
const eventTemplate = {
|
||||
content: "",
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: ProfileBadges,
|
||||
tags
|
||||
};
|
||||
return eventTemplate;
|
||||
}
|
||||
function validateProfileBadgesEvent(event) {
|
||||
if (event.kind !== ProfileBadges)
|
||||
return false;
|
||||
const requiredTags = ["d"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip58.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip58.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
298
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip59.js
generated
vendored
Normal file
298
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip59.js
generated
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip59.ts
|
||||
var nip59_exports = {};
|
||||
__export(nip59_exports, {
|
||||
createRumor: () => createRumor,
|
||||
createSeal: () => createSeal,
|
||||
createWrap: () => createWrap,
|
||||
unwrapEvent: () => unwrapEvent,
|
||||
unwrapManyEvents: () => unwrapManyEvents,
|
||||
wrapEvent: () => wrapEvent,
|
||||
wrapManyEvents: () => wrapManyEvents
|
||||
});
|
||||
module.exports = __toCommonJS(nip59_exports);
|
||||
|
||||
// nip44.ts
|
||||
var import_chacha = require("@noble/ciphers/chacha");
|
||||
var import_utils2 = require("@noble/ciphers/utils");
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_hkdf = require("@noble/hashes/hkdf");
|
||||
var import_hmac = require("@noble/hashes/hmac");
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
var import_utils3 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip44.ts
|
||||
var minPlaintextSize = 1;
|
||||
var maxPlaintextSize = 65535;
|
||||
function getConversationKey(privkeyA, pubkeyB) {
|
||||
const sharedX = import_secp256k1.secp256k1.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
|
||||
return (0, import_hkdf.extract)(import_sha256.sha256, sharedX, "nip44-v2");
|
||||
}
|
||||
function getMessageKeys(conversationKey, nonce) {
|
||||
const keys = (0, import_hkdf.expand)(import_sha256.sha256, conversationKey, nonce, 76);
|
||||
return {
|
||||
chacha_key: keys.subarray(0, 32),
|
||||
chacha_nonce: keys.subarray(32, 44),
|
||||
hmac_key: keys.subarray(44, 76)
|
||||
};
|
||||
}
|
||||
function calcPaddedLen(len) {
|
||||
if (!Number.isSafeInteger(len) || len < 1)
|
||||
throw new Error("expected positive integer");
|
||||
if (len <= 32)
|
||||
return 32;
|
||||
const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;
|
||||
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
|
||||
return chunk * (Math.floor((len - 1) / chunk) + 1);
|
||||
}
|
||||
function writeU16BE(num) {
|
||||
if (!Number.isSafeInteger(num) || num < minPlaintextSize || num > maxPlaintextSize)
|
||||
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
|
||||
const arr = new Uint8Array(2);
|
||||
new DataView(arr.buffer).setUint16(0, num, false);
|
||||
return arr;
|
||||
}
|
||||
function pad(plaintext) {
|
||||
const unpadded = utf8Encoder.encode(plaintext);
|
||||
const unpaddedLen = unpadded.length;
|
||||
const prefix = writeU16BE(unpaddedLen);
|
||||
const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen);
|
||||
return (0, import_utils3.concatBytes)(prefix, unpadded, suffix);
|
||||
}
|
||||
function unpad(padded) {
|
||||
const unpaddedLen = new DataView(padded.buffer).getUint16(0);
|
||||
const unpadded = padded.subarray(2, 2 + unpaddedLen);
|
||||
if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + calcPaddedLen(unpaddedLen))
|
||||
throw new Error("invalid padding");
|
||||
return utf8Decoder.decode(unpadded);
|
||||
}
|
||||
function hmacAad(key, message, aad) {
|
||||
if (aad.length !== 32)
|
||||
throw new Error("AAD associated data must be 32 bytes");
|
||||
const combined = (0, import_utils3.concatBytes)(aad, message);
|
||||
return (0, import_hmac.hmac)(import_sha256.sha256, key, combined);
|
||||
}
|
||||
function decodePayload(payload) {
|
||||
if (typeof payload !== "string")
|
||||
throw new Error("payload must be a valid string");
|
||||
const plen = payload.length;
|
||||
if (plen < 132 || plen > 87472)
|
||||
throw new Error("invalid payload length: " + plen);
|
||||
if (payload[0] === "#")
|
||||
throw new Error("unknown encryption version");
|
||||
let data;
|
||||
try {
|
||||
data = import_base.base64.decode(payload);
|
||||
} catch (error) {
|
||||
throw new Error("invalid base64: " + error.message);
|
||||
}
|
||||
const dlen = data.length;
|
||||
if (dlen < 99 || dlen > 65603)
|
||||
throw new Error("invalid data length: " + dlen);
|
||||
const vers = data[0];
|
||||
if (vers !== 2)
|
||||
throw new Error("unknown encryption version " + vers);
|
||||
return {
|
||||
nonce: data.subarray(1, 33),
|
||||
ciphertext: data.subarray(33, -32),
|
||||
mac: data.subarray(-32)
|
||||
};
|
||||
}
|
||||
function encrypt(plaintext, conversationKey, nonce = (0, import_utils3.randomBytes)(32)) {
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const padded = pad(plaintext);
|
||||
const ciphertext = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, padded);
|
||||
const mac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
return import_base.base64.encode((0, import_utils3.concatBytes)(new Uint8Array([2]), nonce, ciphertext, mac));
|
||||
}
|
||||
function decrypt(payload, conversationKey) {
|
||||
const { nonce, ciphertext, mac } = decodePayload(payload);
|
||||
const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);
|
||||
const calculatedMac = hmacAad(hmac_key, ciphertext, nonce);
|
||||
if (!(0, import_utils2.equalBytes)(calculatedMac, mac))
|
||||
throw new Error("invalid MAC");
|
||||
const padded = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, ciphertext);
|
||||
return unpad(padded);
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k12 = require("@noble/curves/secp256k1");
|
||||
var import_utils5 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha2562 = require("@noble/hashes/sha256");
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k12.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils5.bytesToHex)(import_secp256k12.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils5.bytesToHex)(import_secp256k12.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils5.bytesToHex)(import_secp256k12.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k12.schnorr.verify(event.sig, hash, 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 = (0, import_sha2562.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils5.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var Seal = 13;
|
||||
var GiftWrap = 1059;
|
||||
|
||||
// nip59.ts
|
||||
var TWO_DAYS = 2 * 24 * 60 * 60;
|
||||
var now = () => Math.round(Date.now() / 1e3);
|
||||
var randomNow = () => Math.round(now() - Math.random() * TWO_DAYS);
|
||||
var nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey);
|
||||
var nip44Encrypt = (data, privateKey, publicKey) => encrypt(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey));
|
||||
var nip44Decrypt = (data, privateKey) => JSON.parse(decrypt(data.content, nip44ConversationKey(privateKey, data.pubkey)));
|
||||
function createRumor(event, privateKey) {
|
||||
const rumor = {
|
||||
created_at: now(),
|
||||
content: "",
|
||||
tags: [],
|
||||
...event,
|
||||
pubkey: getPublicKey(privateKey)
|
||||
};
|
||||
rumor.id = getEventHash(rumor);
|
||||
return rumor;
|
||||
}
|
||||
function createSeal(rumor, privateKey, recipientPublicKey) {
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: Seal,
|
||||
content: nip44Encrypt(rumor, privateKey, recipientPublicKey),
|
||||
created_at: randomNow(),
|
||||
tags: []
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
}
|
||||
function createWrap(seal, recipientPublicKey) {
|
||||
const randomKey = generateSecretKey();
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: GiftWrap,
|
||||
content: nip44Encrypt(seal, randomKey, recipientPublicKey),
|
||||
created_at: randomNow(),
|
||||
tags: [["p", recipientPublicKey]]
|
||||
},
|
||||
randomKey
|
||||
);
|
||||
}
|
||||
function wrapEvent(event, senderPrivateKey, recipientPublicKey) {
|
||||
const rumor = createRumor(event, senderPrivateKey);
|
||||
const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey);
|
||||
return createWrap(seal, recipientPublicKey);
|
||||
}
|
||||
function wrapManyEvents(event, senderPrivateKey, recipientsPublicKeys) {
|
||||
if (!recipientsPublicKeys || recipientsPublicKeys.length === 0) {
|
||||
throw new Error("At least one recipient is required.");
|
||||
}
|
||||
const senderPublicKey = getPublicKey(senderPrivateKey);
|
||||
const wrappeds = [wrapEvent(event, senderPrivateKey, senderPublicKey)];
|
||||
recipientsPublicKeys.forEach((recipientPublicKey) => {
|
||||
wrappeds.push(wrapEvent(event, senderPrivateKey, recipientPublicKey));
|
||||
});
|
||||
return wrappeds;
|
||||
}
|
||||
function unwrapEvent(wrap, recipientPrivateKey) {
|
||||
const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey);
|
||||
return nip44Decrypt(unwrappedSeal, recipientPrivateKey);
|
||||
}
|
||||
function unwrapManyEvents(wrappedEvents, recipientPrivateKey) {
|
||||
let unwrappedEvents = [];
|
||||
wrappedEvents.forEach((e) => {
|
||||
unwrappedEvents.push(unwrapEvent(e, recipientPrivateKey));
|
||||
});
|
||||
unwrappedEvents.sort((a, b) => a.created_at - b.created_at);
|
||||
return unwrappedEvents;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip59.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip59.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
70
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip75.js
generated
vendored
Normal file
70
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip75.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip75.ts
|
||||
var nip75_exports = {};
|
||||
__export(nip75_exports, {
|
||||
generateGoalEventTemplate: () => generateGoalEventTemplate,
|
||||
validateZapGoalEvent: () => validateZapGoalEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip75_exports);
|
||||
|
||||
// kinds.ts
|
||||
var ZapGoal = 9041;
|
||||
|
||||
// nip75.ts
|
||||
function generateGoalEventTemplate({
|
||||
amount,
|
||||
content,
|
||||
relays,
|
||||
a,
|
||||
closedAt,
|
||||
image,
|
||||
r,
|
||||
summary,
|
||||
zapTags
|
||||
}) {
|
||||
const tags = [
|
||||
["amount", amount],
|
||||
["relays", ...relays]
|
||||
];
|
||||
closedAt && tags.push(["closed_at", closedAt.toString()]);
|
||||
image && tags.push(["image", image]);
|
||||
summary && tags.push(["summary", summary]);
|
||||
r && tags.push(["r", r]);
|
||||
a && tags.push(["a", a]);
|
||||
zapTags && tags.push(...zapTags);
|
||||
const eventTemplate = {
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: ZapGoal,
|
||||
content,
|
||||
tags
|
||||
};
|
||||
return eventTemplate;
|
||||
}
|
||||
function validateZapGoalEvent(event) {
|
||||
if (event.kind !== ZapGoal)
|
||||
return false;
|
||||
const requiredTags = ["amount", "relays"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip75.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip75.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
142
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip94.js
generated
vendored
Normal file
142
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip94.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip94.ts
|
||||
var nip94_exports = {};
|
||||
__export(nip94_exports, {
|
||||
generateEventTemplate: () => generateEventTemplate,
|
||||
parseEvent: () => parseEvent,
|
||||
validateEvent: () => validateEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip94_exports);
|
||||
|
||||
// kinds.ts
|
||||
var FileMetadata = 1063;
|
||||
|
||||
// nip94.ts
|
||||
function generateEventTemplate(fileMetadata) {
|
||||
const eventTemplate = {
|
||||
content: fileMetadata.content,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
kind: FileMetadata,
|
||||
tags: [
|
||||
["url", fileMetadata.url],
|
||||
["m", fileMetadata.m],
|
||||
["x", fileMetadata.x],
|
||||
["ox", fileMetadata.ox]
|
||||
]
|
||||
};
|
||||
if (fileMetadata.size)
|
||||
eventTemplate.tags.push(["size", fileMetadata.size]);
|
||||
if (fileMetadata.dim)
|
||||
eventTemplate.tags.push(["dim", fileMetadata.dim]);
|
||||
if (fileMetadata.i)
|
||||
eventTemplate.tags.push(["i", fileMetadata.i]);
|
||||
if (fileMetadata.blurhash)
|
||||
eventTemplate.tags.push(["blurhash", fileMetadata.blurhash]);
|
||||
if (fileMetadata.thumb)
|
||||
eventTemplate.tags.push(["thumb", fileMetadata.thumb]);
|
||||
if (fileMetadata.image)
|
||||
eventTemplate.tags.push(["image", fileMetadata.image]);
|
||||
if (fileMetadata.summary)
|
||||
eventTemplate.tags.push(["summary", fileMetadata.summary]);
|
||||
if (fileMetadata.alt)
|
||||
eventTemplate.tags.push(["alt", fileMetadata.alt]);
|
||||
if (fileMetadata.fallback)
|
||||
fileMetadata.fallback.forEach((url) => eventTemplate.tags.push(["fallback", url]));
|
||||
return eventTemplate;
|
||||
}
|
||||
function validateEvent(event) {
|
||||
if (event.kind !== FileMetadata)
|
||||
return false;
|
||||
if (!event.content)
|
||||
return false;
|
||||
const requiredTags = ["url", "m", "x", "ox"];
|
||||
for (const tag of requiredTags) {
|
||||
if (!event.tags.find(([t]) => t == tag))
|
||||
return false;
|
||||
}
|
||||
const sizeTag = event.tags.find(([t]) => t == "size");
|
||||
if (sizeTag && isNaN(Number(sizeTag[1])))
|
||||
return false;
|
||||
const dimTag = event.tags.find(([t]) => t == "dim");
|
||||
if (dimTag && !dimTag[1].match(/^\d+x\d+$/))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function parseEvent(event) {
|
||||
if (!validateEvent(event)) {
|
||||
throw new Error("Invalid event");
|
||||
}
|
||||
const fileMetadata = {
|
||||
content: event.content,
|
||||
url: "",
|
||||
m: "",
|
||||
x: "",
|
||||
ox: ""
|
||||
};
|
||||
for (const [tag, value] of event.tags) {
|
||||
switch (tag) {
|
||||
case "url":
|
||||
fileMetadata.url = value;
|
||||
break;
|
||||
case "m":
|
||||
fileMetadata.m = value;
|
||||
break;
|
||||
case "x":
|
||||
fileMetadata.x = value;
|
||||
break;
|
||||
case "ox":
|
||||
fileMetadata.ox = value;
|
||||
break;
|
||||
case "size":
|
||||
fileMetadata.size = value;
|
||||
break;
|
||||
case "dim":
|
||||
fileMetadata.dim = value;
|
||||
break;
|
||||
case "magnet":
|
||||
fileMetadata.magnet = value;
|
||||
break;
|
||||
case "i":
|
||||
fileMetadata.i = value;
|
||||
break;
|
||||
case "blurhash":
|
||||
fileMetadata.blurhash = value;
|
||||
break;
|
||||
case "thumb":
|
||||
fileMetadata.thumb = value;
|
||||
break;
|
||||
case "image":
|
||||
fileMetadata.image = value;
|
||||
break;
|
||||
case "summary":
|
||||
fileMetadata.summary = value;
|
||||
break;
|
||||
case "alt":
|
||||
fileMetadata.alt = value;
|
||||
break;
|
||||
case "fallback":
|
||||
fileMetadata.fallback ??= [];
|
||||
fileMetadata.fallback.push(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fileMetadata;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip94.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip94.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
230
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip98.js
generated
vendored
Normal file
230
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip98.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip98.ts
|
||||
var nip98_exports = {};
|
||||
__export(nip98_exports, {
|
||||
getToken: () => getToken,
|
||||
hashPayload: () => hashPayload,
|
||||
unpackEventFromToken: () => unpackEventFromToken,
|
||||
validateEvent: () => validateEvent2,
|
||||
validateEventKind: () => validateEventKind,
|
||||
validateEventMethodTag: () => validateEventMethodTag,
|
||||
validateEventPayloadTag: () => validateEventPayloadTag,
|
||||
validateEventTimestamp: () => validateEventTimestamp,
|
||||
validateEventUrlTag: () => validateEventUrlTag,
|
||||
validateToken: () => validateToken
|
||||
});
|
||||
module.exports = __toCommonJS(nip98_exports);
|
||||
var import_sha2562 = require("@noble/hashes/sha256");
|
||||
var import_utils4 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var HTTPAuth = 27235;
|
||||
|
||||
// nip98.ts
|
||||
var _authorizationScheme = "Nostr ";
|
||||
async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false, payload) {
|
||||
const event = {
|
||||
kind: HTTPAuth,
|
||||
tags: [
|
||||
["u", loginUrl],
|
||||
["method", httpMethod]
|
||||
],
|
||||
created_at: Math.round(new Date().getTime() / 1e3),
|
||||
content: ""
|
||||
};
|
||||
if (payload) {
|
||||
event.tags.push(["payload", hashPayload(payload)]);
|
||||
}
|
||||
const signedEvent = await sign(event);
|
||||
const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
|
||||
return authorizationScheme + import_base.base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
|
||||
}
|
||||
async function validateToken(token, url, method) {
|
||||
const event = await unpackEventFromToken(token).catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
const valid = await validateEvent2(event, url, method).catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
return valid;
|
||||
}
|
||||
async function unpackEventFromToken(token) {
|
||||
if (!token) {
|
||||
throw new Error("Missing token");
|
||||
}
|
||||
token = token.replace(_authorizationScheme, "");
|
||||
const eventB64 = utf8Decoder.decode(import_base.base64.decode(token));
|
||||
if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {
|
||||
throw new Error("Invalid token");
|
||||
}
|
||||
const event = JSON.parse(eventB64);
|
||||
return event;
|
||||
}
|
||||
function validateEventTimestamp(event) {
|
||||
if (!event.created_at) {
|
||||
return false;
|
||||
}
|
||||
return Math.round(new Date().getTime() / 1e3) - event.created_at < 60;
|
||||
}
|
||||
function validateEventKind(event) {
|
||||
return event.kind === HTTPAuth;
|
||||
}
|
||||
function validateEventUrlTag(event, url) {
|
||||
const urlTag = event.tags.find((t) => t[0] === "u");
|
||||
if (!urlTag) {
|
||||
return false;
|
||||
}
|
||||
return urlTag.length > 0 && urlTag[1] === url;
|
||||
}
|
||||
function validateEventMethodTag(event, method) {
|
||||
const methodTag = event.tags.find((t) => t[0] === "method");
|
||||
if (!methodTag) {
|
||||
return false;
|
||||
}
|
||||
return methodTag.length > 0 && methodTag[1].toLowerCase() === method.toLowerCase();
|
||||
}
|
||||
function hashPayload(payload) {
|
||||
const hash = (0, import_sha2562.sha256)(utf8Encoder.encode(JSON.stringify(payload)));
|
||||
return (0, import_utils4.bytesToHex)(hash);
|
||||
}
|
||||
function validateEventPayloadTag(event, payload) {
|
||||
const payloadTag = event.tags.find((t) => t[0] === "payload");
|
||||
if (!payloadTag) {
|
||||
return false;
|
||||
}
|
||||
const payloadHash = hashPayload(payload);
|
||||
return payloadTag.length > 0 && payloadTag[1] === payloadHash;
|
||||
}
|
||||
async function validateEvent2(event, url, method, body) {
|
||||
if (!verifyEvent(event)) {
|
||||
throw new Error("Invalid nostr event, signature invalid");
|
||||
}
|
||||
if (!validateEventKind(event)) {
|
||||
throw new Error("Invalid nostr event, kind invalid");
|
||||
}
|
||||
if (!validateEventTimestamp(event)) {
|
||||
throw new Error("Invalid nostr event, created_at timestamp invalid");
|
||||
}
|
||||
if (!validateEventUrlTag(event, url)) {
|
||||
throw new Error("Invalid nostr event, url tag invalid");
|
||||
}
|
||||
if (!validateEventMethodTag(event, method)) {
|
||||
throw new Error("Invalid nostr event, method tag invalid");
|
||||
}
|
||||
if (Boolean(body) && typeof body === "object" && Object.keys(body).length > 0) {
|
||||
if (!validateEventPayloadTag(event, body)) {
|
||||
throw new Error("Invalid nostr event, payload tag does not match request body hash");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip98.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip98.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
153
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip99.js
generated
vendored
Normal file
153
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip99.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nip99.ts
|
||||
var nip99_exports = {};
|
||||
__export(nip99_exports, {
|
||||
generateEventTemplate: () => generateEventTemplate,
|
||||
parseEvent: () => parseEvent,
|
||||
validateEvent: () => validateEvent
|
||||
});
|
||||
module.exports = __toCommonJS(nip99_exports);
|
||||
|
||||
// kinds.ts
|
||||
var ClassifiedListing = 30402;
|
||||
var DraftClassifiedListing = 30403;
|
||||
|
||||
// nip99.ts
|
||||
function validateEvent(event) {
|
||||
if (![ClassifiedListing, DraftClassifiedListing].includes(event.kind))
|
||||
return false;
|
||||
const requiredTags = ["d", "title", "summary", "location", "published_at", "price"];
|
||||
const requiredTagCount = requiredTags.length;
|
||||
const tagCounts = {};
|
||||
if (event.tags.length < requiredTagCount)
|
||||
return false;
|
||||
for (const tag of event.tags) {
|
||||
if (tag.length < 2)
|
||||
return false;
|
||||
const [tagName, ...tagValues] = tag;
|
||||
if (tagName == "published_at") {
|
||||
const timestamp = parseInt(tagValues[0]);
|
||||
if (isNaN(timestamp))
|
||||
return false;
|
||||
} else if (tagName == "price") {
|
||||
if (tagValues.length < 2)
|
||||
return false;
|
||||
const price = parseInt(tagValues[0]);
|
||||
if (isNaN(price) || tagValues[1].length != 3)
|
||||
return false;
|
||||
} else if ((tagName == "e" || tagName == "a") && tag.length != 3) {
|
||||
return false;
|
||||
}
|
||||
if (requiredTags.includes(tagName)) {
|
||||
tagCounts[tagName] = (tagCounts[tagName] || 0) + 1;
|
||||
}
|
||||
}
|
||||
return Object.values(tagCounts).every((count) => count == 1) && Object.keys(tagCounts).length == requiredTagCount;
|
||||
}
|
||||
function parseEvent(event) {
|
||||
if (!validateEvent(event)) {
|
||||
throw new Error("Invalid event");
|
||||
}
|
||||
const listing = {
|
||||
isDraft: event.kind === DraftClassifiedListing,
|
||||
title: "",
|
||||
summary: "",
|
||||
content: event.content,
|
||||
publishedAt: "",
|
||||
location: "",
|
||||
price: {
|
||||
amount: "",
|
||||
currency: ""
|
||||
},
|
||||
images: [],
|
||||
hashtags: [],
|
||||
additionalTags: {}
|
||||
};
|
||||
for (let i = 0; i < event.tags.length; i++) {
|
||||
const tag = event.tags[i];
|
||||
const [tagName, ...tagValues] = tag;
|
||||
if (tagName == "title") {
|
||||
listing.title = tagValues[0];
|
||||
} else if (tagName == "summary") {
|
||||
listing.summary = tagValues[0];
|
||||
} else if (tagName == "published_at") {
|
||||
listing.publishedAt = tagValues[0];
|
||||
} else if (tagName == "location") {
|
||||
listing.location = tagValues[0];
|
||||
} else if (tagName == "price") {
|
||||
listing.price.amount = tagValues[0];
|
||||
listing.price.currency = tagValues[1];
|
||||
if (tagValues.length == 3) {
|
||||
listing.price.frequency = tagValues[2];
|
||||
}
|
||||
} else if (tagName == "image") {
|
||||
listing.images.push({
|
||||
url: tagValues[0],
|
||||
dimensions: tagValues?.[1] ?? void 0
|
||||
});
|
||||
} else if (tagName == "t") {
|
||||
listing.hashtags.push(tagValues[0]);
|
||||
} else if (tagName == "e" || tagName == "a") {
|
||||
listing.additionalTags[tagName] = [...tagValues];
|
||||
}
|
||||
}
|
||||
return listing;
|
||||
}
|
||||
function generateEventTemplate(listing) {
|
||||
const priceTag = ["price", listing.price.amount, listing.price.currency];
|
||||
if (listing.price.frequency)
|
||||
priceTag.push(listing.price.frequency);
|
||||
const tags = [
|
||||
["d", listing.title.trim().toLowerCase().replace(/ /g, "-")],
|
||||
["title", listing.title],
|
||||
["published_at", listing.publishedAt],
|
||||
["summary", listing.summary],
|
||||
["location", listing.location],
|
||||
priceTag
|
||||
];
|
||||
for (let i = 0; i < listing.images.length; i++) {
|
||||
const image = listing.images[i];
|
||||
const imageTag = ["image", image.url];
|
||||
if (image.dimensions)
|
||||
imageTag.push(image.dimensions);
|
||||
tags.push(imageTag);
|
||||
}
|
||||
for (let i = 0; i < listing.hashtags.length; i++) {
|
||||
const t = listing.hashtags[i];
|
||||
tags.push(["t", t]);
|
||||
}
|
||||
for (const [key, value] of Object.entries(listing.additionalTags)) {
|
||||
if (Array.isArray(value)) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const val = value[i];
|
||||
tags.push([key, val]);
|
||||
}
|
||||
} else {
|
||||
tags.push([key, value]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
kind: listing.isDraft ? DraftClassifiedListing : ClassifiedListing,
|
||||
content: listing.content,
|
||||
tags,
|
||||
created_at: Math.floor(Date.now() / 1e3)
|
||||
};
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip99.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nip99.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
184
thrower_daemon/node_modules/nostr-tools/lib/cjs/nipb7.js
generated
vendored
Normal file
184
thrower_daemon/node_modules/nostr-tools/lib/cjs/nipb7.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// nipb7.ts
|
||||
var nipb7_exports = {};
|
||||
__export(nipb7_exports, {
|
||||
BlossomClient: () => BlossomClient
|
||||
});
|
||||
module.exports = __toCommonJS(nipb7_exports);
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nipb7.ts
|
||||
var BlossomClient = class {
|
||||
mediaserver;
|
||||
signer;
|
||||
constructor(mediaserver, signer) {
|
||||
if (!mediaserver.startsWith("http")) {
|
||||
mediaserver = "https://" + mediaserver;
|
||||
}
|
||||
this.mediaserver = mediaserver.replace(/\/$/, "") + "/";
|
||||
this.signer = signer;
|
||||
}
|
||||
async httpCall(method, url, contentType, addAuthorization, body, result) {
|
||||
const headers = {};
|
||||
if (contentType) {
|
||||
headers["Content-Type"] = contentType;
|
||||
}
|
||||
if (addAuthorization) {
|
||||
const auth = await addAuthorization();
|
||||
if (auth) {
|
||||
headers["Authorization"] = auth;
|
||||
}
|
||||
}
|
||||
const response = await fetch(this.mediaserver + url, {
|
||||
method,
|
||||
headers,
|
||||
body
|
||||
});
|
||||
if (response.status >= 300) {
|
||||
const reason = response.headers.get("X-Reason") || response.statusText;
|
||||
throw new Error(`${url} returned an error (${response.status}): ${reason}`);
|
||||
}
|
||||
if (result !== null && response.headers.get("content-type")?.includes("application/json")) {
|
||||
return await response.json();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
async authorizationHeader(modify) {
|
||||
const now = Math.floor(Date.now() / 1e3);
|
||||
const event = {
|
||||
created_at: now,
|
||||
kind: 24242,
|
||||
content: "blossom stuff",
|
||||
tags: [["expiration", String(now + 60)]]
|
||||
};
|
||||
if (modify) {
|
||||
modify(event);
|
||||
}
|
||||
try {
|
||||
const signedEvent = await this.signer.signEvent(event);
|
||||
const eventJson = JSON.stringify(signedEvent);
|
||||
return "Nostr " + btoa(eventJson);
|
||||
} catch (error) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
isValid32ByteHex(hash) {
|
||||
return /^[a-f0-9]{64}$/i.test(hash);
|
||||
}
|
||||
async check(hash) {
|
||||
if (!this.isValid32ByteHex(hash)) {
|
||||
throw new Error(`${hash} is not a valid 32-byte hex string`);
|
||||
}
|
||||
try {
|
||||
await this.httpCall("HEAD", hash);
|
||||
} catch (error) {
|
||||
throw new Error(`failed to check for ${hash}: ${error}`);
|
||||
}
|
||||
}
|
||||
async uploadBlob(file, contentType) {
|
||||
const hash = (0, import_utils.bytesToHex)((0, import_sha256.sha256)(new Uint8Array(await file.arrayBuffer())));
|
||||
const actualContentType = contentType || file.type || "application/octet-stream";
|
||||
const bd = await this.httpCall(
|
||||
"PUT",
|
||||
"upload",
|
||||
actualContentType,
|
||||
() => this.authorizationHeader((evt) => {
|
||||
evt.tags.push(["t", "upload"]);
|
||||
evt.tags.push(["x", hash]);
|
||||
}),
|
||||
file,
|
||||
{}
|
||||
);
|
||||
return bd;
|
||||
}
|
||||
async uploadFile(file) {
|
||||
return this.uploadBlob(file, file.type);
|
||||
}
|
||||
async download(hash) {
|
||||
if (!this.isValid32ByteHex(hash)) {
|
||||
throw new Error(`${hash} is not a valid 32-byte hex string`);
|
||||
}
|
||||
const authHeader = await this.authorizationHeader((evt) => {
|
||||
evt.tags.push(["t", "get"]);
|
||||
evt.tags.push(["x", hash]);
|
||||
});
|
||||
const response = await fetch(this.mediaserver + hash, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: authHeader
|
||||
}
|
||||
});
|
||||
if (response.status >= 300) {
|
||||
throw new Error(`${hash} is not present in ${this.mediaserver}: ${response.status}`);
|
||||
}
|
||||
return await response.arrayBuffer();
|
||||
}
|
||||
async downloadAsBlob(hash) {
|
||||
const arrayBuffer = await this.download(hash);
|
||||
return new Blob([arrayBuffer]);
|
||||
}
|
||||
async list() {
|
||||
const pubkey = await this.signer.getPublicKey();
|
||||
if (!this.isValid32ByteHex(pubkey)) {
|
||||
throw new Error(`pubkey ${pubkey} is not valid`);
|
||||
}
|
||||
try {
|
||||
const bds = await this.httpCall(
|
||||
"GET",
|
||||
`list/${pubkey}`,
|
||||
void 0,
|
||||
() => this.authorizationHeader((evt) => {
|
||||
evt.tags.push(["t", "list"]);
|
||||
}),
|
||||
void 0,
|
||||
[]
|
||||
);
|
||||
return bds;
|
||||
} catch (error) {
|
||||
throw new Error(`failed to list blobs: ${error}`);
|
||||
}
|
||||
}
|
||||
async delete(hash) {
|
||||
if (!this.isValid32ByteHex(hash)) {
|
||||
throw new Error(`${hash} is not a valid 32-byte hex string`);
|
||||
}
|
||||
try {
|
||||
await this.httpCall(
|
||||
"DELETE",
|
||||
hash,
|
||||
void 0,
|
||||
() => this.authorizationHeader((evt) => {
|
||||
evt.tags.push(["t", "delete"]);
|
||||
evt.tags.push(["x", hash]);
|
||||
}),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(`failed to delete ${hash}: ${error}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nipb7.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/nipb7.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
thrower_daemon/node_modules/nostr-tools/lib/cjs/package.json
generated
vendored
Normal file
1
thrower_daemon/node_modules/nostr-tools/lib/cjs/package.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"type":"commonjs"}
|
||||
896
thrower_daemon/node_modules/nostr-tools/lib/cjs/pool.js
generated
vendored
Normal file
896
thrower_daemon/node_modules/nostr-tools/lib/cjs/pool.js
generated
vendored
Normal file
@@ -0,0 +1,896 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// pool.ts
|
||||
var pool_exports = {};
|
||||
__export(pool_exports, {
|
||||
AbstractSimplePool: () => AbstractSimplePool,
|
||||
SimplePool: () => SimplePool,
|
||||
useWebSocketImplementation: () => useWebSocketImplementation
|
||||
});
|
||||
module.exports = __toCommonJS(pool_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i2 = 0; i2 < filters.length; i2++) {
|
||||
if (matchFilter(filters[i2], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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;
|
||||
};
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
|
||||
// abstract-pool.ts
|
||||
var AbstractSimplePool = class {
|
||||
relays = /* @__PURE__ */ new Map();
|
||||
seenOn = /* @__PURE__ */ new Map();
|
||||
trackRelays = false;
|
||||
verifyEvent;
|
||||
enablePing;
|
||||
trustedRelayURLs = /* @__PURE__ */ new Set();
|
||||
_WebSocket;
|
||||
constructor(opts) {
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
async ensureRelay(url, params) {
|
||||
url = normalizeURL(url);
|
||||
let relay = this.relays.get(url);
|
||||
if (!relay) {
|
||||
relay = new AbstractRelay(url, {
|
||||
verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,
|
||||
websocketImplementation: this._WebSocket,
|
||||
enablePing: this.enablePing
|
||||
});
|
||||
relay.onclose = () => {
|
||||
this.relays.delete(url);
|
||||
};
|
||||
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();
|
||||
this.relays.delete(url);
|
||||
});
|
||||
}
|
||||
subscribe(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
for (let i2 = 0; i2 < relays.length; i2++) {
|
||||
const url = normalizeURL(relays[i2]);
|
||||
if (!request.find((r) => r.url === url)) {
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMany(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
const uniqUrls = [];
|
||||
for (let i2 = 0; i2 < relays.length; i2++) {
|
||||
const url = normalizeURL(relays[i2]);
|
||||
if (uniqUrls.indexOf(url) === -1) {
|
||||
uniqUrls.push(url);
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMap(requests, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const grouped = /* @__PURE__ */ new Map();
|
||||
for (const req of requests) {
|
||||
const { url, filter } = req;
|
||||
if (!grouped.has(url))
|
||||
grouped.set(url, []);
|
||||
grouped.get(url).push(filter);
|
||||
}
|
||||
const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters }));
|
||||
if (this.trackRelays) {
|
||||
params.receivedEvent = (relay, id) => {
|
||||
let set = this.seenOn.get(id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(id, set);
|
||||
}
|
||||
set.add(relay);
|
||||
};
|
||||
}
|
||||
const _knownIds = /* @__PURE__ */ new Set();
|
||||
const subs = [];
|
||||
const eosesReceived = [];
|
||||
let handleEose = (i2) => {
|
||||
if (eosesReceived[i2])
|
||||
return;
|
||||
eosesReceived[i2] = true;
|
||||
if (eosesReceived.filter((a) => a).length === requests.length) {
|
||||
params.oneose?.();
|
||||
handleEose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const closesReceived = [];
|
||||
let handleClose = (i2, reason) => {
|
||||
if (closesReceived[i2])
|
||||
return;
|
||||
handleEose(i2);
|
||||
closesReceived[i2] = reason;
|
||||
if (closesReceived.filter((a) => a).length === requests.length) {
|
||||
params.onclose?.(closesReceived);
|
||||
handleClose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const localAlreadyHaveEventHandler = (id) => {
|
||||
if (params.alreadyHaveEvent?.(id)) {
|
||||
return true;
|
||||
}
|
||||
const have = _knownIds.has(id);
|
||||
_knownIds.add(id);
|
||||
return have;
|
||||
};
|
||||
const allOpened = Promise.all(
|
||||
groupedRequests.map(async ({ url, filters }, i2) => {
|
||||
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) => {
|
||||
if (reason.startsWith("auth-required: ") && params.onauth) {
|
||||
relay.auth(params.onauth).then(() => {
|
||||
relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i2),
|
||||
onclose: (reason2) => {
|
||||
handleClose(i2, reason2);
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
}).catch((err) => {
|
||||
handleClose(i2, `auth was required and attempted, but failed with: ${err}`);
|
||||
});
|
||||
} else {
|
||||
handleClose(i2, reason);
|
||||
}
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
subs.push(subscription);
|
||||
})
|
||||
);
|
||||
return {
|
||||
async close(reason) {
|
||||
await allOpened;
|
||||
subs.forEach((sub) => {
|
||||
sub.close(reason);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
subscribeEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribe(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
subscribeManyEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribeMany(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
async querySync(relays, filter, params) {
|
||||
return new Promise(async (resolve) => {
|
||||
const events = [];
|
||||
this.subscribeEose(relays, filter, {
|
||||
...params,
|
||||
onevent(event) {
|
||||
events.push(event);
|
||||
},
|
||||
onclose(_) {
|
||||
resolve(events);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
async get(relays, filter, params) {
|
||||
filter.limit = 1;
|
||||
const events = await this.querySync(relays, filter, params);
|
||||
events.sort((a, b) => b.created_at - a.created_at);
|
||||
return events[0] || null;
|
||||
}
|
||||
publish(relays, event, options) {
|
||||
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).catch(async (err) => {
|
||||
if (err instanceof Error && err.message.startsWith("auth-required: ") && options?.onauth) {
|
||||
await r.auth(options.onauth);
|
||||
return r.publish(event);
|
||||
}
|
||||
throw err;
|
||||
}).then((reason) => {
|
||||
if (this.trackRelays) {
|
||||
let set = this.seenOn.get(event.id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(event.id, set);
|
||||
}
|
||||
set.add(r);
|
||||
}
|
||||
return reason;
|
||||
});
|
||||
});
|
||||
}
|
||||
listConnectionStatus() {
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
this.relays.forEach((relay, url) => map.set(url, relay.connected));
|
||||
return map;
|
||||
}
|
||||
destroy() {
|
||||
this.relays.forEach((conn) => conn.close());
|
||||
this.relays = /* @__PURE__ */ new Map();
|
||||
}
|
||||
};
|
||||
|
||||
// pool.ts
|
||||
var _WebSocket;
|
||||
try {
|
||||
_WebSocket = WebSocket;
|
||||
} catch {
|
||||
}
|
||||
function useWebSocketImplementation(websocketImplementation) {
|
||||
_WebSocket = websocketImplementation;
|
||||
}
|
||||
var SimplePool = class extends AbstractSimplePool {
|
||||
constructor(options) {
|
||||
super({ verifyEvent, websocketImplementation: _WebSocket, ...options });
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/pool.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/pool.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
130
thrower_daemon/node_modules/nostr-tools/lib/cjs/pure.js
generated
vendored
Normal file
130
thrower_daemon/node_modules/nostr-tools/lib/cjs/pure.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// pure.ts
|
||||
var pure_exports = {};
|
||||
__export(pure_exports, {
|
||||
finalizeEvent: () => finalizeEvent,
|
||||
generateSecretKey: () => generateSecretKey,
|
||||
getEventHash: () => getEventHash,
|
||||
getPublicKey: () => getPublicKey,
|
||||
serializeEvent: () => serializeEvent,
|
||||
sortEvents: () => sortEvents,
|
||||
validateEvent: () => validateEvent,
|
||||
verifiedSymbol: () => verifiedSymbol,
|
||||
verifyEvent: () => verifyEvent
|
||||
});
|
||||
module.exports = __toCommonJS(pure_exports);
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function sortEvents(events) {
|
||||
return events.sort((a, b) => {
|
||||
if (a.created_at !== b.created_at) {
|
||||
return b.created_at - a.created_at;
|
||||
}
|
||||
return a.id.localeCompare(b.id);
|
||||
});
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/pure.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/pure.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
210
thrower_daemon/node_modules/nostr-tools/lib/cjs/references.js
generated
vendored
Normal file
210
thrower_daemon/node_modules/nostr-tools/lib/cjs/references.js
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// references.ts
|
||||
var references_exports = {};
|
||||
__export(references_exports, {
|
||||
parseReferences: () => parseReferences
|
||||
});
|
||||
module.exports = __toCommonJS(references_exports);
|
||||
|
||||
// nip19.ts
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
var import_base = require("@scure/base");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// nip19.ts
|
||||
var Bech32MaxSize = 5e3;
|
||||
function decode(code) {
|
||||
let { prefix, words } = import_base.bech32.decode(code, Bech32MaxSize);
|
||||
let data = new Uint8Array(import_base.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: (0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[0][0]),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
||||
author: tlv[2]?.[0] ? (0, import_utils2.bytesToHex)(tlv[2][0]) : void 0,
|
||||
kind: tlv[3]?.[0] ? parseInt((0, import_utils2.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: (0, import_utils2.bytesToHex)(tlv[2][0]),
|
||||
kind: parseInt((0, import_utils2.bytesToHex)(tlv[3][0]), 16),
|
||||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
||||
}
|
||||
};
|
||||
}
|
||||
case "nsec":
|
||||
return { type: prefix, data };
|
||||
case "npub":
|
||||
case "note":
|
||||
return { type: prefix, data: (0, import_utils2.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;
|
||||
}
|
||||
|
||||
// references.ts
|
||||
var mentionRegex = /\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g;
|
||||
function parseReferences(evt) {
|
||||
let references = [];
|
||||
for (let ref of evt.content.matchAll(mentionRegex)) {
|
||||
if (ref[2]) {
|
||||
try {
|
||||
let { type, data } = decode(ref[1]);
|
||||
switch (type) {
|
||||
case "npub": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: { pubkey: data, relays: [] }
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "nprofile": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: data
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "note": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: { id: data, relays: [] }
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "nevent": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: data
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "naddr": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
address: data
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
} else if (ref[3]) {
|
||||
let idx = parseInt(ref[3], 10);
|
||||
let tag = evt.tags[idx];
|
||||
if (!tag)
|
||||
continue;
|
||||
switch (tag[0]) {
|
||||
case "p": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: { pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] }
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "e": {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: { id: tag[1], relays: tag[2] ? [tag[2]] : [] }
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "a": {
|
||||
try {
|
||||
let [kind, pubkey, identifier] = tag[1].split(":");
|
||||
references.push({
|
||||
text: ref[0],
|
||||
address: {
|
||||
identifier,
|
||||
pubkey,
|
||||
kind: parseInt(kind, 10),
|
||||
relays: tag[2] ? [tag[2]] : []
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return references;
|
||||
}
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/references.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/references.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
659
thrower_daemon/node_modules/nostr-tools/lib/cjs/relay.js
generated
vendored
Normal file
659
thrower_daemon/node_modules/nostr-tools/lib/cjs/relay.js
generated
vendored
Normal file
@@ -0,0 +1,659 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// relay.ts
|
||||
var relay_exports = {};
|
||||
__export(relay_exports, {
|
||||
AbstractRelay: () => AbstractRelay,
|
||||
Relay: () => Relay,
|
||||
SendingOnClosedConnection: () => SendingOnClosedConnection,
|
||||
Subscription: () => Subscription,
|
||||
useWebSocketImplementation: () => useWebSocketImplementation
|
||||
});
|
||||
module.exports = __toCommonJS(relay_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i2 = 0; i2 < filters.length; i2++) {
|
||||
if (matchFilter(filters[i2], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
|
||||
// relay.ts
|
||||
var _WebSocket;
|
||||
try {
|
||||
_WebSocket = WebSocket;
|
||||
} catch {
|
||||
}
|
||||
function useWebSocketImplementation(websocketImplementation) {
|
||||
_WebSocket = websocketImplementation;
|
||||
}
|
||||
var Relay = class extends AbstractRelay {
|
||||
constructor(url) {
|
||||
super(url, { verifyEvent, websocketImplementation: _WebSocket });
|
||||
}
|
||||
static async connect(url) {
|
||||
const relay = new Relay(url);
|
||||
await relay.connect();
|
||||
return relay;
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/relay.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/relay.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
130
thrower_daemon/node_modules/nostr-tools/lib/cjs/signer.js
generated
vendored
Normal file
130
thrower_daemon/node_modules/nostr-tools/lib/cjs/signer.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// signer.ts
|
||||
var signer_exports = {};
|
||||
__export(signer_exports, {
|
||||
PlainKeySigner: () => PlainKeySigner
|
||||
});
|
||||
module.exports = __toCommonJS(signer_exports);
|
||||
|
||||
// pure.ts
|
||||
var import_secp256k1 = require("@noble/curves/secp256k1");
|
||||
var import_utils2 = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// pure.ts
|
||||
var import_sha256 = require("@noble/hashes/sha256");
|
||||
|
||||
// utils.ts
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return import_secp256k1.schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = (0, import_utils2.bytesToHex)(import_secp256k1.schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = import_secp256k1.schnorr.verify(event.sig, hash, 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 = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event)));
|
||||
return (0, import_utils2.bytesToHex)(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// signer.ts
|
||||
var PlainKeySigner = class {
|
||||
secretKey;
|
||||
constructor(secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
async getPublicKey() {
|
||||
return getPublicKey(this.secretKey);
|
||||
}
|
||||
async signEvent(event) {
|
||||
return finalizeEvent(event, this.secretKey);
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/signer.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/signer.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
145
thrower_daemon/node_modules/nostr-tools/lib/cjs/utils.js
generated
vendored
Normal file
145
thrower_daemon/node_modules/nostr-tools/lib/cjs/utils.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// utils.ts
|
||||
var utils_exports = {};
|
||||
__export(utils_exports, {
|
||||
Queue: () => Queue,
|
||||
QueueNode: () => QueueNode,
|
||||
binarySearch: () => binarySearch,
|
||||
bytesToHex: () => import_utils.bytesToHex,
|
||||
hexToBytes: () => import_utils.hexToBytes,
|
||||
insertEventIntoAscendingList: () => insertEventIntoAscendingList,
|
||||
insertEventIntoDescendingList: () => insertEventIntoDescendingList,
|
||||
normalizeURL: () => normalizeURL,
|
||||
utf8Decoder: () => utf8Decoder,
|
||||
utf8Encoder: () => utf8Encoder
|
||||
});
|
||||
module.exports = __toCommonJS(utils_exports);
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
function insertEventIntoDescendingList(sortedArray, event) {
|
||||
const [idx, found] = binarySearch(sortedArray, (b) => {
|
||||
if (event.id === b.id)
|
||||
return 0;
|
||||
if (event.created_at === b.created_at)
|
||||
return -1;
|
||||
return b.created_at - event.created_at;
|
||||
});
|
||||
if (!found) {
|
||||
sortedArray.splice(idx, 0, event);
|
||||
}
|
||||
return sortedArray;
|
||||
}
|
||||
function insertEventIntoAscendingList(sortedArray, event) {
|
||||
const [idx, found] = binarySearch(sortedArray, (b) => {
|
||||
if (event.id === b.id)
|
||||
return 0;
|
||||
if (event.created_at === b.created_at)
|
||||
return -1;
|
||||
return event.created_at - b.created_at;
|
||||
});
|
||||
if (!found) {
|
||||
sortedArray.splice(idx, 0, event);
|
||||
}
|
||||
return sortedArray;
|
||||
}
|
||||
function binarySearch(arr, compare) {
|
||||
let start = 0;
|
||||
let end = arr.length - 1;
|
||||
while (start <= end) {
|
||||
const mid = Math.floor((start + end) / 2);
|
||||
const cmp = compare(arr[mid]);
|
||||
if (cmp === 0) {
|
||||
return [mid, true];
|
||||
}
|
||||
if (cmp < 0) {
|
||||
end = mid - 1;
|
||||
} else {
|
||||
start = mid + 1;
|
||||
}
|
||||
}
|
||||
return [start, false];
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/utils.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/utils.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../utils.ts"],
|
||||
"sourcesContent": ["import type { Event } from './core.ts'\n\nexport const utf8Decoder: TextDecoder = new TextDecoder('utf-8')\nexport const utf8Encoder: TextEncoder = new TextEncoder()\n\nexport { bytesToHex, hexToBytes } from '@noble/hashes/utils'\n\nexport function normalizeURL(url: string): string {\n try {\n if (url.indexOf('://') === -1) url = 'wss://' + url\n let p = new URL(url)\n p.pathname = p.pathname.replace(/\\/+/g, '/')\n if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)\n if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:')) p.port = ''\n p.searchParams.sort()\n p.hash = ''\n return p.toString()\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`)\n }\n}\n\nexport function insertEventIntoDescendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return b.created_at - event.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function insertEventIntoAscendingList(sortedArray: Event[], event: Event): Event[] {\n const [idx, found] = binarySearch(sortedArray, b => {\n if (event.id === b.id) return 0\n if (event.created_at === b.created_at) return -1\n return event.created_at - b.created_at\n })\n if (!found) {\n sortedArray.splice(idx, 0, event)\n }\n return sortedArray\n}\n\nexport function binarySearch<T>(arr: T[], compare: (b: T) => number): [number, boolean] {\n let start = 0\n let end = arr.length - 1\n\n while (start <= end) {\n const mid = Math.floor((start + end) / 2)\n const cmp = compare(arr[mid])\n\n if (cmp === 0) {\n return [mid, true]\n }\n\n if (cmp < 0) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return [start, false]\n}\n\nexport class QueueNode<V> {\n public value: V\n public next: QueueNode<V> | null = null\n public prev: QueueNode<V> | null = null\n\n constructor(message: V) {\n this.value = message\n }\n}\n\nexport class Queue<V> {\n public first: QueueNode<V> | null\n public last: QueueNode<V> | null\n\n constructor() {\n this.first = null\n this.last = null\n }\n\n enqueue(value: V): boolean {\n const newNode = new QueueNode(value)\n if (!this.last) {\n // list is empty\n this.first = newNode\n this.last = newNode\n } else if (this.last === this.first) {\n // list has a single element\n this.last = newNode\n this.last.prev = this.first\n this.first.next = newNode\n } else {\n // list has elements, add as last\n newNode.prev = this.last\n this.last.next = newNode\n this.last = newNode\n }\n return true\n }\n\n dequeue(): V | null {\n if (!this.first) return null\n\n if (this.first === this.last) {\n const target = this.first\n this.first = null\n this.last = null\n return target.value\n }\n\n const target = this.first\n this.first = target.next\n if (this.first) {\n this.first.prev = null // fix: clean up prev pointer\n }\n\n return target.value\n }\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,mBAAuC;AAHhC,IAAM,cAA2B,IAAI,YAAY,OAAO;AACxD,IAAM,cAA2B,IAAI,YAAY;AAIjD,SAAS,aAAa,KAAqB;AAChD,MAAI;AACF,QAAI,IAAI,QAAQ,KAAK,MAAM;AAAI,YAAM,WAAW;AAChD,QAAI,IAAI,IAAI,IAAI,GAAG;AACnB,MAAE,WAAW,EAAE,SAAS,QAAQ,QAAQ,GAAG;AAC3C,QAAI,EAAE,SAAS,SAAS,GAAG;AAAG,QAAE,WAAW,EAAE,SAAS,MAAM,GAAG,EAAE;AACjE,QAAK,EAAE,SAAS,QAAQ,EAAE,aAAa,SAAW,EAAE,SAAS,SAAS,EAAE,aAAa;AAAS,QAAE,OAAO;AACvG,MAAE,aAAa,KAAK;AACpB,MAAE,OAAO;AACT,WAAO,EAAE,SAAS;AAAA,EACpB,SAAS,GAAP;AACA,UAAM,IAAI,MAAM,gBAAgB,KAAK;AAAA,EACvC;AACF;AAEO,SAAS,8BAA8B,aAAsB,OAAuB;AACzF,QAAM,CAAC,KAAK,KAAK,IAAI,aAAa,aAAa,OAAK;AAClD,QAAI,MAAM,OAAO,EAAE;AAAI,aAAO;AAC9B,QAAI,MAAM,eAAe,EAAE;AAAY,aAAO;AAC9C,WAAO,EAAE,aAAa,MAAM;AAAA,EAC9B,CAAC;AACD,MAAI,CAAC,OAAO;AACV,gBAAY,OAAO,KAAK,GAAG,KAAK;AAAA,EAClC;AACA,SAAO;AACT;AAEO,SAAS,6BAA6B,aAAsB,OAAuB;AACxF,QAAM,CAAC,KAAK,KAAK,IAAI,aAAa,aAAa,OAAK;AAClD,QAAI,MAAM,OAAO,EAAE;AAAI,aAAO;AAC9B,QAAI,MAAM,eAAe,EAAE;AAAY,aAAO;AAC9C,WAAO,MAAM,aAAa,EAAE;AAAA,EAC9B,CAAC;AACD,MAAI,CAAC,OAAO;AACV,gBAAY,OAAO,KAAK,GAAG,KAAK;AAAA,EAClC;AACA,SAAO;AACT;AAEO,SAAS,aAAgB,KAAU,SAA8C;AACtF,MAAI,QAAQ;AACZ,MAAI,MAAM,IAAI,SAAS;AAEvB,SAAO,SAAS,KAAK;AACnB,UAAM,MAAM,KAAK,OAAO,QAAQ,OAAO,CAAC;AACxC,UAAM,MAAM,QAAQ,IAAI,IAAI;AAE5B,QAAI,QAAQ,GAAG;AACb,aAAO,CAAC,KAAK,IAAI;AAAA,IACnB;AAEA,QAAI,MAAM,GAAG;AACX,YAAM,MAAM;AAAA,IACd,OAAO;AACL,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAEA,SAAO,CAAC,OAAO,KAAK;AACtB;AAEO,IAAM,YAAN,MAAmB;AAAA,EACjB;AAAA,EACA,OAA4B;AAAA,EAC5B,OAA4B;AAAA,EAEnC,YAAY,SAAY;AACtB,SAAK,QAAQ;AAAA,EACf;AACF;AAEO,IAAM,QAAN,MAAe;AAAA,EACb;AAAA,EACA;AAAA,EAEP,cAAc;AACZ,SAAK,QAAQ;AACb,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,QAAQ,OAAmB;AACzB,UAAM,UAAU,IAAI,UAAU,KAAK;AACnC,QAAI,CAAC,KAAK,MAAM;AAEd,WAAK,QAAQ;AACb,WAAK,OAAO;AAAA,IACd,WAAW,KAAK,SAAS,KAAK,OAAO;AAEnC,WAAK,OAAO;AACZ,WAAK,KAAK,OAAO,KAAK;AACtB,WAAK,MAAM,OAAO;AAAA,IACpB,OAAO;AAEL,cAAQ,OAAO,KAAK;AACpB,WAAK,KAAK,OAAO;AACjB,WAAK,OAAO;AAAA,IACd;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UAAoB;AAClB,QAAI,CAAC,KAAK;AAAO,aAAO;AAExB,QAAI,KAAK,UAAU,KAAK,MAAM;AAC5B,YAAMA,UAAS,KAAK;AACpB,WAAK,QAAQ;AACb,WAAK,OAAO;AACZ,aAAOA,QAAO;AAAA,IAChB;AAEA,UAAM,SAAS,KAAK;AACpB,SAAK,QAAQ,OAAO;AACpB,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,OAAO;AAAA,IACpB;AAEA,WAAO,OAAO;AAAA,EAChB;AACF;",
|
||||
"names": ["target"]
|
||||
}
|
||||
103
thrower_daemon/node_modules/nostr-tools/lib/cjs/wasm.js
generated
vendored
Normal file
103
thrower_daemon/node_modules/nostr-tools/lib/cjs/wasm.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// wasm.ts
|
||||
var wasm_exports = {};
|
||||
__export(wasm_exports, {
|
||||
finalizeEvent: () => finalizeEvent,
|
||||
generateSecretKey: () => generateSecretKey,
|
||||
getPublicKey: () => getPublicKey,
|
||||
setNostrWasm: () => setNostrWasm,
|
||||
sortEvents: () => sortEvents,
|
||||
validateEvent: () => validateEvent,
|
||||
verifiedSymbol: () => verifiedSymbol,
|
||||
verifyEvent: () => verifyEvent
|
||||
});
|
||||
module.exports = __toCommonJS(wasm_exports);
|
||||
var import_utils = require("@noble/hashes/utils");
|
||||
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
var isRecord = (obj) => obj instanceof Object;
|
||||
function validateEvent(event) {
|
||||
if (!isRecord(event))
|
||||
return false;
|
||||
if (typeof event.kind !== "number")
|
||||
return false;
|
||||
if (typeof event.content !== "string")
|
||||
return false;
|
||||
if (typeof event.created_at !== "number")
|
||||
return false;
|
||||
if (typeof event.pubkey !== "string")
|
||||
return false;
|
||||
if (!event.pubkey.match(/^[a-f0-9]{64}$/))
|
||||
return false;
|
||||
if (!Array.isArray(event.tags))
|
||||
return false;
|
||||
for (let i2 = 0; i2 < event.tags.length; i2++) {
|
||||
let tag = event.tags[i2];
|
||||
if (!Array.isArray(tag))
|
||||
return false;
|
||||
for (let j = 0; j < tag.length; j++) {
|
||||
if (typeof tag[j] !== "string")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function sortEvents(events) {
|
||||
return events.sort((a, b) => {
|
||||
if (a.created_at !== b.created_at) {
|
||||
return b.created_at - a.created_at;
|
||||
}
|
||||
return a.id.localeCompare(b.id);
|
||||
});
|
||||
}
|
||||
|
||||
// wasm.ts
|
||||
var nw;
|
||||
function setNostrWasm(x) {
|
||||
nw = x;
|
||||
}
|
||||
var Wasm = class {
|
||||
generateSecretKey() {
|
||||
return nw.generateSecretKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return (0, import_utils.bytesToHex)(nw.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
nw.finalizeEvent(t, secretKey);
|
||||
return t;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
try {
|
||||
nw.verifyEvent(event);
|
||||
event[verifiedSymbol] = true;
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
var i = new Wasm();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/wasm.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/cjs/wasm.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../wasm.ts", "../../core.ts"],
|
||||
"sourcesContent": ["import { bytesToHex } from '@noble/hashes/utils'\nimport { Nostr as NostrWasm } from 'nostr-wasm'\nimport { EventTemplate, Event, Nostr, VerifiedEvent, verifiedSymbol } from './core.ts'\n\nlet nw: NostrWasm\n\nexport function setNostrWasm(x: NostrWasm) {\n nw = x\n}\n\nclass Wasm implements Nostr {\n generateSecretKey(): Uint8Array {\n return nw.generateSecretKey()\n }\n getPublicKey(secretKey: Uint8Array): string {\n return bytesToHex(nw.getPublicKey(secretKey))\n }\n finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {\n nw.finalizeEvent(t as any, secretKey)\n return t as VerifiedEvent\n }\n verifyEvent(event: Event): event is VerifiedEvent {\n try {\n nw.verifyEvent(event)\n event[verifiedSymbol] = true\n return true\n } catch (err) {\n return false\n }\n }\n}\n\nconst i: Wasm = new Wasm()\nexport const generateSecretKey = i.generateSecretKey\nexport const getPublicKey = i.getPublicKey\nexport const finalizeEvent = i.finalizeEvent\nexport const verifyEvent = i.verifyEvent\nexport * from './core.ts'\n", "export interface Nostr {\n generateSecretKey(): Uint8Array\n getPublicKey(secretKey: Uint8Array): string\n finalizeEvent(event: EventTemplate, secretKey: Uint8Array): VerifiedEvent\n verifyEvent(event: Event): event is VerifiedEvent\n}\n\n/** Designates a verified event signature. */\nexport const verifiedSymbol = Symbol('verified')\n\nexport interface Event {\n kind: number\n tags: string[][]\n content: string\n created_at: number\n pubkey: string\n id: string\n sig: string\n [verifiedSymbol]?: boolean\n}\n\nexport type NostrEvent = Event\nexport type EventTemplate = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at'>\nexport type UnsignedEvent = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'>\n\n/** An event whose signature has been verified. */\nexport interface VerifiedEvent extends Event {\n [verifiedSymbol]: true\n}\n\nconst isRecord = (obj: unknown): obj is Record<string, unknown> => obj instanceof Object\n\nexport function validateEvent<T>(event: T): event is T & UnsignedEvent {\n if (!isRecord(event)) return false\n if (typeof event.kind !== 'number') return false\n if (typeof event.content !== 'string') return false\n if (typeof event.created_at !== 'number') return false\n if (typeof event.pubkey !== 'string') return false\n if (!event.pubkey.match(/^[a-f0-9]{64}$/)) return false\n\n if (!Array.isArray(event.tags)) return false\n for (let i = 0; i < event.tags.length; i++) {\n let tag = event.tags[i]\n if (!Array.isArray(tag)) return false\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== 'string') return false\n }\n }\n\n return true\n}\n\n/**\n * Sort events in reverse-chronological order by the `created_at` timestamp,\n * and then by the event `id` (lexicographically) in case of ties.\n * This mutates the array.\n */\nexport function sortEvents(events: Event[]): Event[] {\n return events.sort((a: NostrEvent, b: NostrEvent): number => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at\n }\n return a.id.localeCompare(b.id)\n })\n}\n"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2B;;;ACQpB,IAAM,iBAAiB,OAAO,UAAU;AAsB/C,IAAM,WAAW,CAAC,QAAiD,eAAe;AAE3E,SAAS,cAAiB,OAAsC;AACrE,MAAI,CAAC,SAAS,KAAK;AAAG,WAAO;AAC7B,MAAI,OAAO,MAAM,SAAS;AAAU,WAAO;AAC3C,MAAI,OAAO,MAAM,YAAY;AAAU,WAAO;AAC9C,MAAI,OAAO,MAAM,eAAe;AAAU,WAAO;AACjD,MAAI,OAAO,MAAM,WAAW;AAAU,WAAO;AAC7C,MAAI,CAAC,MAAM,OAAO,MAAM,gBAAgB;AAAG,WAAO;AAElD,MAAI,CAAC,MAAM,QAAQ,MAAM,IAAI;AAAG,WAAO;AACvC,WAASA,KAAI,GAAGA,KAAI,MAAM,KAAK,QAAQA,MAAK;AAC1C,QAAI,MAAM,MAAM,KAAKA;AACrB,QAAI,CAAC,MAAM,QAAQ,GAAG;AAAG,aAAO;AAChC,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,OAAO,IAAI,OAAO;AAAU,eAAO;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,WAAW,QAA0B;AACnD,SAAO,OAAO,KAAK,CAAC,GAAe,MAA0B;AAC3D,QAAI,EAAE,eAAe,EAAE,YAAY;AACjC,aAAO,EAAE,aAAa,EAAE;AAAA,IAC1B;AACA,WAAO,EAAE,GAAG,cAAc,EAAE,EAAE;AAAA,EAChC,CAAC;AACH;;;AD5DA,IAAI;AAEG,SAAS,aAAa,GAAc;AACzC,OAAK;AACP;AAEA,IAAM,OAAN,MAA4B;AAAA,EAC1B,oBAAgC;AAC9B,WAAO,GAAG,kBAAkB;AAAA,EAC9B;AAAA,EACA,aAAa,WAA+B;AAC1C,eAAO,yBAAW,GAAG,aAAa,SAAS,CAAC;AAAA,EAC9C;AAAA,EACA,cAAc,GAAkB,WAAsC;AACpE,OAAG,cAAc,GAAU,SAAS;AACpC,WAAO;AAAA,EACT;AAAA,EACA,YAAY,OAAsC;AAChD,QAAI;AACF,SAAG,YAAY,KAAK;AACpB,YAAM,kBAAkB;AACxB,aAAO;AAAA,IACT,SAAS,KAAP;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,IAAM,IAAU,IAAI,KAAK;AAClB,IAAM,oBAAoB,EAAE;AAC5B,IAAM,eAAe,EAAE;AACvB,IAAM,gBAAgB,EAAE;AACxB,IAAM,cAAc,EAAE;",
|
||||
"names": ["i"]
|
||||
}
|
||||
773
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-pool.js
generated
vendored
Normal file
773
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-pool.js
generated
vendored
Normal file
@@ -0,0 +1,773 @@
|
||||
// core.ts
|
||||
var verifiedSymbol = Symbol("verified");
|
||||
|
||||
// utils.ts
|
||||
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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;
|
||||
};
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
|
||||
// abstract-pool.ts
|
||||
var AbstractSimplePool = class {
|
||||
relays = /* @__PURE__ */ new Map();
|
||||
seenOn = /* @__PURE__ */ new Map();
|
||||
trackRelays = false;
|
||||
verifyEvent;
|
||||
enablePing;
|
||||
trustedRelayURLs = /* @__PURE__ */ new Set();
|
||||
_WebSocket;
|
||||
constructor(opts) {
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
async ensureRelay(url, params) {
|
||||
url = normalizeURL(url);
|
||||
let relay = this.relays.get(url);
|
||||
if (!relay) {
|
||||
relay = new AbstractRelay(url, {
|
||||
verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,
|
||||
websocketImplementation: this._WebSocket,
|
||||
enablePing: this.enablePing
|
||||
});
|
||||
relay.onclose = () => {
|
||||
this.relays.delete(url);
|
||||
};
|
||||
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();
|
||||
this.relays.delete(url);
|
||||
});
|
||||
}
|
||||
subscribe(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
for (let i = 0; i < relays.length; i++) {
|
||||
const url = normalizeURL(relays[i]);
|
||||
if (!request.find((r) => r.url === url)) {
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMany(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const request = [];
|
||||
const uniqUrls = [];
|
||||
for (let i = 0; i < relays.length; i++) {
|
||||
const url = normalizeURL(relays[i]);
|
||||
if (uniqUrls.indexOf(url) === -1) {
|
||||
uniqUrls.push(url);
|
||||
request.push({ url, filter });
|
||||
}
|
||||
}
|
||||
return this.subscribeMap(request, params);
|
||||
}
|
||||
subscribeMap(requests, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const grouped = /* @__PURE__ */ new Map();
|
||||
for (const req of requests) {
|
||||
const { url, filter } = req;
|
||||
if (!grouped.has(url))
|
||||
grouped.set(url, []);
|
||||
grouped.get(url).push(filter);
|
||||
}
|
||||
const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters }));
|
||||
if (this.trackRelays) {
|
||||
params.receivedEvent = (relay, id) => {
|
||||
let set = this.seenOn.get(id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(id, set);
|
||||
}
|
||||
set.add(relay);
|
||||
};
|
||||
}
|
||||
const _knownIds = /* @__PURE__ */ new Set();
|
||||
const subs = [];
|
||||
const eosesReceived = [];
|
||||
let handleEose = (i) => {
|
||||
if (eosesReceived[i])
|
||||
return;
|
||||
eosesReceived[i] = true;
|
||||
if (eosesReceived.filter((a) => a).length === requests.length) {
|
||||
params.oneose?.();
|
||||
handleEose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const closesReceived = [];
|
||||
let handleClose = (i, reason) => {
|
||||
if (closesReceived[i])
|
||||
return;
|
||||
handleEose(i);
|
||||
closesReceived[i] = reason;
|
||||
if (closesReceived.filter((a) => a).length === requests.length) {
|
||||
params.onclose?.(closesReceived);
|
||||
handleClose = () => {
|
||||
};
|
||||
}
|
||||
};
|
||||
const localAlreadyHaveEventHandler = (id) => {
|
||||
if (params.alreadyHaveEvent?.(id)) {
|
||||
return true;
|
||||
}
|
||||
const have = _knownIds.has(id);
|
||||
_knownIds.add(id);
|
||||
return have;
|
||||
};
|
||||
const allOpened = Promise.all(
|
||||
groupedRequests.map(async ({ url, filters }, i) => {
|
||||
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(i, err?.message || String(err));
|
||||
return;
|
||||
}
|
||||
let subscription = relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i),
|
||||
onclose: (reason) => {
|
||||
if (reason.startsWith("auth-required: ") && params.onauth) {
|
||||
relay.auth(params.onauth).then(() => {
|
||||
relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i),
|
||||
onclose: (reason2) => {
|
||||
handleClose(i, reason2);
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
}).catch((err) => {
|
||||
handleClose(i, `auth was required and attempted, but failed with: ${err}`);
|
||||
});
|
||||
} else {
|
||||
handleClose(i, reason);
|
||||
}
|
||||
},
|
||||
alreadyHaveEvent: localAlreadyHaveEventHandler,
|
||||
eoseTimeout: params.maxWait
|
||||
});
|
||||
subs.push(subscription);
|
||||
})
|
||||
);
|
||||
return {
|
||||
async close(reason) {
|
||||
await allOpened;
|
||||
subs.forEach((sub) => {
|
||||
sub.close(reason);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
subscribeEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribe(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
subscribeManyEose(relays, filter, params) {
|
||||
params.onauth = params.onauth || params.doauth;
|
||||
const subcloser = this.subscribeMany(relays, filter, {
|
||||
...params,
|
||||
oneose() {
|
||||
subcloser.close("closed automatically on eose");
|
||||
}
|
||||
});
|
||||
return subcloser;
|
||||
}
|
||||
async querySync(relays, filter, params) {
|
||||
return new Promise(async (resolve) => {
|
||||
const events = [];
|
||||
this.subscribeEose(relays, filter, {
|
||||
...params,
|
||||
onevent(event) {
|
||||
events.push(event);
|
||||
},
|
||||
onclose(_) {
|
||||
resolve(events);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
async get(relays, filter, params) {
|
||||
filter.limit = 1;
|
||||
const events = await this.querySync(relays, filter, params);
|
||||
events.sort((a, b) => b.created_at - a.created_at);
|
||||
return events[0] || null;
|
||||
}
|
||||
publish(relays, event, options) {
|
||||
return relays.map(normalizeURL).map(async (url, i, arr) => {
|
||||
if (arr.indexOf(url) !== i) {
|
||||
return Promise.reject("duplicate url");
|
||||
}
|
||||
let r = await this.ensureRelay(url);
|
||||
return r.publish(event).catch(async (err) => {
|
||||
if (err instanceof Error && err.message.startsWith("auth-required: ") && options?.onauth) {
|
||||
await r.auth(options.onauth);
|
||||
return r.publish(event);
|
||||
}
|
||||
throw err;
|
||||
}).then((reason) => {
|
||||
if (this.trackRelays) {
|
||||
let set = this.seenOn.get(event.id);
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this.seenOn.set(event.id, set);
|
||||
}
|
||||
set.add(r);
|
||||
}
|
||||
return reason;
|
||||
});
|
||||
});
|
||||
}
|
||||
listConnectionStatus() {
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
this.relays.forEach((relay, url) => map.set(url, relay.connected));
|
||||
return map;
|
||||
}
|
||||
destroy() {
|
||||
this.relays.forEach((conn) => conn.close());
|
||||
this.relays = /* @__PURE__ */ new Map();
|
||||
}
|
||||
};
|
||||
export {
|
||||
AbstractSimplePool
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-pool.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-pool.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
528
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-relay.js
generated
vendored
Normal file
528
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-relay.js
generated
vendored
Normal file
@@ -0,0 +1,528 @@
|
||||
// utils.ts
|
||||
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
function normalizeURL(url) {
|
||||
try {
|
||||
if (url.indexOf("://") === -1)
|
||||
url = "wss://" + url;
|
||||
let p = new URL(url);
|
||||
p.pathname = p.pathname.replace(/\/+/g, "/");
|
||||
if (p.pathname.endsWith("/"))
|
||||
p.pathname = p.pathname.slice(0, -1);
|
||||
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
|
||||
p.port = "";
|
||||
p.searchParams.sort();
|
||||
p.hash = "";
|
||||
return p.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid URL: ${url}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (this.first) {
|
||||
this.first.prev = null;
|
||||
}
|
||||
return target.value;
|
||||
}
|
||||
};
|
||||
|
||||
// kinds.ts
|
||||
var ClientAuth = 22242;
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fakejson.ts
|
||||
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);
|
||||
}
|
||||
|
||||
// nip42.ts
|
||||
function makeAuthEvent(relayURL, challenge) {
|
||||
return {
|
||||
kind: ClientAuth,
|
||||
created_at: Math.floor(Date.now() / 1e3),
|
||||
tags: [
|
||||
["relay", relayURL],
|
||||
["challenge", challenge]
|
||||
],
|
||||
content: ""
|
||||
};
|
||||
}
|
||||
|
||||
// helpers.ts
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
// abstract-relay.ts
|
||||
var SendingOnClosedConnection = class extends Error {
|
||||
constructor(message, relay) {
|
||||
super(`Tried to send message '${message} on a closed connection to ${relay}.`);
|
||||
this.name = "SendingOnClosedConnection";
|
||||
}
|
||||
};
|
||||
var AbstractRelay = class {
|
||||
url;
|
||||
_connected = false;
|
||||
onclose = null;
|
||||
onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);
|
||||
baseEoseTimeout = 4400;
|
||||
connectionTimeout = 4400;
|
||||
publishTimeout = 4400;
|
||||
pingFrequency = 2e4;
|
||||
pingTimeout = 2e4;
|
||||
openSubs = /* @__PURE__ */ new Map();
|
||||
enablePing;
|
||||
connectionTimeoutHandle;
|
||||
connectionPromise;
|
||||
openCountRequests = /* @__PURE__ */ new Map();
|
||||
openEventPublishes = /* @__PURE__ */ new Map();
|
||||
ws;
|
||||
incomingMessageQueue = new Queue();
|
||||
queueRunning = false;
|
||||
challenge;
|
||||
authPromise;
|
||||
serial = 0;
|
||||
verifyEvent;
|
||||
_WebSocket;
|
||||
constructor(url, opts) {
|
||||
this.url = normalizeURL(url);
|
||||
this.verifyEvent = opts.verifyEvent;
|
||||
this._WebSocket = opts.websocketImplementation || WebSocket;
|
||||
this.enablePing = opts.enablePing;
|
||||
}
|
||||
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.authPromise = 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) {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.ws.onopen = () => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
this._connected = true;
|
||||
if (this.enablePing) {
|
||||
this.pingpong();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
this.ws.onerror = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket error");
|
||||
this._connected = false;
|
||||
this.connectionPromise = void 0;
|
||||
this.onclose?.();
|
||||
this.closeAllSubscriptions("relay connection errored");
|
||||
};
|
||||
this.ws.onclose = (ev) => {
|
||||
clearTimeout(this.connectionTimeoutHandle);
|
||||
reject(ev.message || "websocket closed");
|
||||
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 waitForPingPong() {
|
||||
return new Promise((res, err) => {
|
||||
;
|
||||
this.ws && this.ws.on && this.ws.on("pong", () => res(true)) || err("ws can't listen for pong");
|
||||
this.ws && this.ws.ping && this.ws.ping();
|
||||
});
|
||||
}
|
||||
async waitForDummyReq() {
|
||||
return new Promise((resolve, _) => {
|
||||
const sub = this.subscribe([{ ids: ["a".repeat(64)] }], {
|
||||
oneose: () => {
|
||||
sub.close();
|
||||
resolve(true);
|
||||
},
|
||||
eoseTimeout: this.pingTimeout + 1e3
|
||||
});
|
||||
});
|
||||
}
|
||||
async pingpong() {
|
||||
if (this.ws?.readyState === 1) {
|
||||
const result = await Promise.any([
|
||||
this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),
|
||||
new Promise((res) => setTimeout(() => res(false), this.pingTimeout))
|
||||
]);
|
||||
if (result) {
|
||||
setTimeout(() => this.pingpong(), this.pingFrequency);
|
||||
} else {
|
||||
this.closeAllSubscriptions("pingpong timed out");
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this.ws?.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (ep) {
|
||||
clearTimeout(ep.timeout);
|
||||
if (ok)
|
||||
ep.resolve(reason);
|
||||
else
|
||||
ep.reject(new Error(reason));
|
||||
this.openEventPublishes.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "CLOSED": {
|
||||
const id = data[1];
|
||||
const so = this.openSubs.get(id);
|
||||
if (!so)
|
||||
return;
|
||||
so.closed = true;
|
||||
so.close(data[2]);
|
||||
return;
|
||||
}
|
||||
case "NOTICE":
|
||||
this.onnotice(data[1]);
|
||||
return;
|
||||
case "AUTH": {
|
||||
this.challenge = data[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async send(message) {
|
||||
if (!this.connectionPromise)
|
||||
throw new SendingOnClosedConnection(message, this.url);
|
||||
this.connectionPromise.then(() => {
|
||||
this.ws?.send(message);
|
||||
});
|
||||
}
|
||||
async auth(signAuthEvent) {
|
||||
const challenge = this.challenge;
|
||||
if (!challenge)
|
||||
throw new Error("can't perform auth, no challenge was received");
|
||||
if (this.authPromise)
|
||||
return this.authPromise;
|
||||
this.authPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
||||
let timeout = setTimeout(() => {
|
||||
let ep = this.openEventPublishes.get(evt.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("auth timed out"));
|
||||
this.openEventPublishes.delete(evt.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
||||
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
||||
} catch (err) {
|
||||
console.warn("subscribe auth function failed:", err);
|
||||
}
|
||||
});
|
||||
return this.authPromise;
|
||||
}
|
||||
async publish(event) {
|
||||
const ret = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
const ep = this.openEventPublishes.get(event.id);
|
||||
if (ep) {
|
||||
ep.reject(new Error("publish timed out"));
|
||||
this.openEventPublishes.delete(event.id);
|
||||
}
|
||||
}, this.publishTimeout);
|
||||
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
||||
});
|
||||
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
||||
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 || (params.label ? params.label + ":" : "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.onclose?.();
|
||||
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) {
|
||||
try {
|
||||
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
||||
} catch (err) {
|
||||
if (err instanceof SendingOnClosedConnection) {
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this.closed = true;
|
||||
}
|
||||
this.relay.openSubs.delete(this.id);
|
||||
this.onclose?.(reason);
|
||||
}
|
||||
};
|
||||
export {
|
||||
AbstractRelay,
|
||||
SendingOnClosedConnection,
|
||||
Subscription
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-relay.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/esm/abstract-relay.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
45
thrower_daemon/node_modules/nostr-tools/lib/esm/fakejson.js
generated
vendored
Normal file
45
thrower_daemon/node_modules/nostr-tools/lib/esm/fakejson.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// fakejson.ts
|
||||
function getHex64(json, field) {
|
||||
let len = field.length + 3;
|
||||
let idx = json.indexOf(`"${field}":`) + len;
|
||||
let s = json.slice(idx).indexOf(`"`) + idx + 1;
|
||||
return json.slice(s, s + 64);
|
||||
}
|
||||
function getInt(json, field) {
|
||||
let len = field.length;
|
||||
let idx = json.indexOf(`"${field}":`) + len + 3;
|
||||
let sliced = json.slice(idx);
|
||||
let end = Math.min(sliced.indexOf(","), sliced.indexOf("}"));
|
||||
return parseInt(sliced.slice(0, end), 10);
|
||||
}
|
||||
function getSubscriptionId(json) {
|
||||
let idx = json.slice(0, 22).indexOf(`"EVENT"`);
|
||||
if (idx === -1)
|
||||
return null;
|
||||
let pstart = json.slice(idx + 7 + 1).indexOf(`"`);
|
||||
if (pstart === -1)
|
||||
return null;
|
||||
let start = idx + 7 + 1 + pstart;
|
||||
let pend = json.slice(start + 1, 80).indexOf(`"`);
|
||||
if (pend === -1)
|
||||
return null;
|
||||
let end = start + 1 + pend;
|
||||
return json.slice(start + 1, end);
|
||||
}
|
||||
function matchEventId(json, id) {
|
||||
return id === getHex64(json, "id");
|
||||
}
|
||||
function matchEventPubkey(json, pubkey) {
|
||||
return pubkey === getHex64(json, "pubkey");
|
||||
}
|
||||
function matchEventKind(json, kind) {
|
||||
return kind === getInt(json, "kind");
|
||||
}
|
||||
export {
|
||||
getHex64,
|
||||
getInt,
|
||||
getSubscriptionId,
|
||||
matchEventId,
|
||||
matchEventKind,
|
||||
matchEventPubkey
|
||||
};
|
||||
7
thrower_daemon/node_modules/nostr-tools/lib/esm/fakejson.js.map
generated
vendored
Normal file
7
thrower_daemon/node_modules/nostr-tools/lib/esm/fakejson.js.map
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../../fakejson.ts"],
|
||||
"sourcesContent": ["export function getHex64(json: string, field: string): string {\n let len = field.length + 3\n let idx = json.indexOf(`\"${field}\":`) + len\n let s = json.slice(idx).indexOf(`\"`) + idx + 1\n return json.slice(s, s + 64)\n}\n\nexport function getInt(json: string, field: string): number {\n let len = field.length\n let idx = json.indexOf(`\"${field}\":`) + len + 3\n let sliced = json.slice(idx)\n let end = Math.min(sliced.indexOf(','), sliced.indexOf('}'))\n return parseInt(sliced.slice(0, end), 10)\n}\n\nexport function getSubscriptionId(json: string): string | null {\n let idx = json.slice(0, 22).indexOf(`\"EVENT\"`)\n if (idx === -1) return null\n\n let pstart = json.slice(idx + 7 + 1).indexOf(`\"`)\n if (pstart === -1) return null\n let start = idx + 7 + 1 + pstart\n\n let pend = json.slice(start + 1, 80).indexOf(`\"`)\n if (pend === -1) return null\n let end = start + 1 + pend\n\n return json.slice(start + 1, end)\n}\n\nexport function matchEventId(json: string, id: string): boolean {\n return id === getHex64(json, 'id')\n}\n\nexport function matchEventPubkey(json: string, pubkey: string): boolean {\n return pubkey === getHex64(json, 'pubkey')\n}\n\nexport function matchEventKind(json: string, kind: number): boolean {\n return kind === getInt(json, 'kind')\n}\n"],
|
||||
"mappings": ";AAAO,SAAS,SAAS,MAAc,OAAuB;AAC5D,MAAI,MAAM,MAAM,SAAS;AACzB,MAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI;AACxC,MAAI,IAAI,KAAK,MAAM,GAAG,EAAE,QAAQ,GAAG,IAAI,MAAM;AAC7C,SAAO,KAAK,MAAM,GAAG,IAAI,EAAE;AAC7B;AAEO,SAAS,OAAO,MAAc,OAAuB;AAC1D,MAAI,MAAM,MAAM;AAChB,MAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM;AAC9C,MAAI,SAAS,KAAK,MAAM,GAAG;AAC3B,MAAI,MAAM,KAAK,IAAI,OAAO,QAAQ,GAAG,GAAG,OAAO,QAAQ,GAAG,CAAC;AAC3D,SAAO,SAAS,OAAO,MAAM,GAAG,GAAG,GAAG,EAAE;AAC1C;AAEO,SAAS,kBAAkB,MAA6B;AAC7D,MAAI,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,SAAS;AAC7C,MAAI,QAAQ;AAAI,WAAO;AAEvB,MAAI,SAAS,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,QAAQ,GAAG;AAChD,MAAI,WAAW;AAAI,WAAO;AAC1B,MAAI,QAAQ,MAAM,IAAI,IAAI;AAE1B,MAAI,OAAO,KAAK,MAAM,QAAQ,GAAG,EAAE,EAAE,QAAQ,GAAG;AAChD,MAAI,SAAS;AAAI,WAAO;AACxB,MAAI,MAAM,QAAQ,IAAI;AAEtB,SAAO,KAAK,MAAM,QAAQ,GAAG,GAAG;AAClC;AAEO,SAAS,aAAa,MAAc,IAAqB;AAC9D,SAAO,OAAO,SAAS,MAAM,IAAI;AACnC;AAEO,SAAS,iBAAiB,MAAc,QAAyB;AACtE,SAAO,WAAW,SAAS,MAAM,QAAQ;AAC3C;AAEO,SAAS,eAAe,MAAc,MAAuB;AAClE,SAAO,SAAS,OAAO,MAAM,MAAM;AACrC;",
|
||||
"names": []
|
||||
}
|
||||
88
thrower_daemon/node_modules/nostr-tools/lib/esm/filter.js
generated
vendored
Normal file
88
thrower_daemon/node_modules/nostr-tools/lib/esm/filter.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// kinds.ts
|
||||
function isReplaceableKind(kind) {
|
||||
return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;
|
||||
}
|
||||
function isAddressableKind(kind) {
|
||||
return 3e4 <= kind && kind < 4e4;
|
||||
}
|
||||
|
||||
// filter.ts
|
||||
function matchFilter(filter, event) {
|
||||
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
||||
return false;
|
||||
}
|
||||
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
||||
return false;
|
||||
}
|
||||
for (let f in filter) {
|
||||
if (f[0] === "#") {
|
||||
let tagName = f.slice(1);
|
||||
let values = filter[`#${tagName}`];
|
||||
if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filter.since && event.created_at < filter.since)
|
||||
return false;
|
||||
if (filter.until && event.created_at > filter.until)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function matchFilters(filters, event) {
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
if (matchFilter(filters[i], event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function mergeFilters(...filters) {
|
||||
let result = {};
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
let filter = filters[i];
|
||||
Object.entries(filter).forEach(([property, values]) => {
|
||||
if (property === "kinds" || property === "ids" || property === "authors" || property[0] === "#") {
|
||||
result[property] = result[property] || [];
|
||||
for (let v = 0; v < values.length; v++) {
|
||||
let value = values[v];
|
||||
if (!result[property].includes(value))
|
||||
result[property].push(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (filter.limit && (!result.limit || filter.limit > result.limit))
|
||||
result.limit = filter.limit;
|
||||
if (filter.until && (!result.until || filter.until > result.until))
|
||||
result.until = filter.until;
|
||||
if (filter.since && (!result.since || filter.since < result.since))
|
||||
result.since = filter.since;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getFilterLimit(filter) {
|
||||
if (filter.ids && !filter.ids.length)
|
||||
return 0;
|
||||
if (filter.kinds && !filter.kinds.length)
|
||||
return 0;
|
||||
if (filter.authors && !filter.authors.length)
|
||||
return 0;
|
||||
for (const [key, value] of Object.entries(filter)) {
|
||||
if (key[0] === "#" && Array.isArray(value) && !value.length)
|
||||
return 0;
|
||||
}
|
||||
return Math.min(
|
||||
Math.max(0, filter.limit ?? Infinity),
|
||||
filter.ids?.length ?? Infinity,
|
||||
filter.authors?.length && filter.kinds?.every((kind) => isReplaceableKind(kind)) ? filter.authors.length * filter.kinds.length : Infinity,
|
||||
filter.authors?.length && filter.kinds?.every((kind) => isAddressableKind(kind)) && filter["#d"]?.length ? filter.authors.length * filter.kinds.length * filter["#d"].length : Infinity
|
||||
);
|
||||
}
|
||||
export {
|
||||
getFilterLimit,
|
||||
matchFilter,
|
||||
matchFilters,
|
||||
mergeFilters
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user