create daemon
This commit is contained in:
253
thrower_daemon/node_modules/nostr-tools/lib/esm/nip57.js
generated
vendored
Normal file
253
thrower_daemon/node_modules/nostr-tools/lib/esm/nip57.js
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
// nip57.ts
|
||||
import { bech32 } from "@scure/base";
|
||||
|
||||
// pure.ts
|
||||
import { schnorr } from "@noble/curves/secp256k1";
|
||||
import { bytesToHex as bytesToHex2 } from "@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
|
||||
import { sha256 } from "@noble/hashes/sha256";
|
||||
|
||||
// utils.ts
|
||||
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
||||
var utf8Decoder = new TextDecoder("utf-8");
|
||||
var utf8Encoder = new TextEncoder();
|
||||
|
||||
// pure.ts
|
||||
var JS = class {
|
||||
generateSecretKey() {
|
||||
return schnorr.utils.randomPrivateKey();
|
||||
}
|
||||
getPublicKey(secretKey) {
|
||||
return bytesToHex2(schnorr.getPublicKey(secretKey));
|
||||
}
|
||||
finalizeEvent(t, secretKey) {
|
||||
const event = t;
|
||||
event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey));
|
||||
event.id = getEventHash(event);
|
||||
event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey));
|
||||
event[verifiedSymbol] = true;
|
||||
return event;
|
||||
}
|
||||
verifyEvent(event) {
|
||||
if (typeof event[verifiedSymbol] === "boolean")
|
||||
return event[verifiedSymbol];
|
||||
const hash = getEventHash(event);
|
||||
if (hash !== event.id) {
|
||||
event[verifiedSymbol] = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const valid = 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 = sha256(utf8Encoder.encode(serializeEvent(event)));
|
||||
return bytesToHex2(eventHash);
|
||||
}
|
||||
var i = new JS();
|
||||
var generateSecretKey = i.generateSecretKey;
|
||||
var getPublicKey = i.getPublicKey;
|
||||
var finalizeEvent = i.finalizeEvent;
|
||||
var verifyEvent = i.verifyEvent;
|
||||
|
||||
// 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 } = bech32.decode(lud06, 1e3);
|
||||
let data = 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;
|
||||
}
|
||||
}
|
||||
export {
|
||||
getSatoshisAmountFromBolt11,
|
||||
getZapEndpoint,
|
||||
makeZapReceipt,
|
||||
makeZapRequest,
|
||||
useFetchImplementation,
|
||||
validateZapRequest
|
||||
};
|
||||
Reference in New Issue
Block a user