diff options
| author | Adam Soltys <[email protected]> | 2024-08-26 21:17:43 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-08-26 21:17:43 -0700 |
| commit | fe62cadd6fb4a7e49f7d59401fc74ae0411e32a7 (patch) | |
| tree | aa8f34e1692bd2d638a2c996eeadb58671d07aea /lib/nostr.js | |
| parent | 00e43ddc0bf3d6dd719fc9295d156567fa2fecfb (diff) | |
| download | coinos-server-fe62cadd6fb4a7e49f7d59401fc74ae0411e32a7.tar.gz coinos-server-fe62cadd6fb4a7e49f7d59401fc74ae0411e32a7.zip | |
typescript
Diffstat (limited to 'lib/nostr.js')
| -rw-r--r-- | lib/nostr.js | 280 |
1 files changed, 0 insertions, 280 deletions
diff --git a/lib/nostr.js b/lib/nostr.js deleted file mode 100644 index ccfb4e54..00000000 --- a/lib/nostr.js +++ /dev/null @@ -1,280 +0,0 @@ -import config from "$config"; -import { l } from "$lib/logging"; -import { Relay, RelayPool, calculateId, signId, getPublicKey } from "nostr"; -import { broadcast, emit } from "$lib/sockets"; -import store from "$lib/store"; -import { g, s, db } from "$lib/db"; -import { fail, nada, wait } from "$lib/utils"; -import { nip19 } from "nostr-tools"; - -export const COINOS_PUBKEY = getPublicKey(nip19.decode(config.nostrKey).data); -export let coinos; -export let pool; - -export let fillPool = () => { - try { - pool = RelayPool(config.relays); - pool.on("open", (relay) => { - if (relay.url.includes(config.nostr)) coinos = relay; - relay.subscribe("live", { limit: 1 }); - }); - - pool.on("event", async (relay, sub, ev) => { - if (!coinos) return; - if (timeouts[sub]) timeouts[sub].extend(ev); - try { - let content; - try { - content = JSON.parse(ev.content); - } catch (e) { - content = ev.content; - } - - if (sub === "live") { - let { pubkey } = ev; - - if (Math.abs(Math.floor(Date.now() / 1000) - ev.created_at) > 7200) - return; - - if (seen.includes(ev.id)) return; - seen.push(ev.id); - seen.length > 1000 && seen.shift(); - - if (coinos && ev.kind < 5) { - // coinos.send(["EVENT", ev]); - ev.user = await getUser(pubkey); - // broadcast("event", ev); - - if (ev.kind === 4) { - let uid = await g(`user:${ev.tags[0][1]}`); - if (uid) ev.recipient = await g(`user:${uid}`); - ev.author = ev.user; - emit(uid, "event", ev); - } - } - } else if (sub.includes("profile")) { - let { pubkey } = ev; - let user = await getUser(pubkey); - - if (user.updated > ev.created_at) return; - - if (content.name && user.username === pubkey.substr(0, 6)) - user.username = content.name; - - delete content.name; - - user = { - ...user, - ...content, - updated: ev.created_at, - }; - - await s(`user:${pubkey}`, JSON.stringify(user)); - } else if (sub.includes("messages")) { - let pubkey = sub.split(":")[0]; - await db.sAdd(`${pubkey}:messages`, ev.id); - await s(`ev:${ev.id}`, ev); - } else if (sub.includes("follows")) { - let pubkey = sub.split(":")[0]; - await s(`${pubkey}:follows`, ev.tags); - for (let f of ev.tags) { - let [_, followPubkey] = f; - await db.sAdd(`${followPubkey}:followers`, pubkey); - } - coinos.send(ev); - } else if (sub.includes("followers")) { - let followed = sub.split(":")[0]; - let { pubkey } = ev; - await db.sAdd(`${followed}:followers`, pubkey); - coinos.send(ev); - } else if (sub.includes("notes")) { - let pubkey = sub.split(":")[0]; - await db.sAdd(pubkey, ev.id); - await s(`ev:${ev.id}`, ev); - } - } catch (e) { - console.log(e); - } - }); - } catch(e) { - console.log("POOL", e) - } -}; - -let now = () => Math.round(Date.now() / 1000); - -let timeouts = {}; -export let q = async ( - sub, - query, - { timeout = 20000, since = 3600, eager = 200 }, -) => - new Promise(async (r, j) => { - let start = Date.now(); - let seen = []; - let rejected; - // query.since = await g(`since:${sub}`); - // if (now() - query.since < since) return r(); - - let done = { [sub]: [] }; - - let check = (s) => { - let elapsed = Date.now() - start; - if (rejected) return true; - if ( - done[s] && - (done[s].length === pool.relays.length || - (done[s].length && elapsed > eager)) - ) { - r(); - if (timeouts[s]) timeouts[s].clear(); - return true; - } - }; - - timeouts[sub] = { - async clear() { - clearTimeout(this.timer); - delete timeouts[sub]; - pool.unsubscribe(sub); - await s(`since:${sub}`, now()); - }, - extend(ev) { - if (ev) { - if (seen.includes(ev.id)) return; - seen.push(ev.id); - seen.length > 1000 && seen.shift(); - } - - clearTimeout(this.timer); - this.timer = setTimeout(() => { - j(new Error(`query timed out: ${sub} ${Date.now()}`)); - pool.unsubscribe(sub); - rejected = true; - }, timeout); - }, - timer: undefined, - }; - - timeouts[sub].extend(); - pool.subscribe(sub, query); - - pool.on("eose", (relay, s) => { - if (done[s]) done[s].push(relay.url); - check(s); - }); - - try { - await wait(() => check(sub), 100, 200); - } catch (e) { - console.log(e); - } - }); - -let seen = []; - -let getUser = async (pubkey) => { - let id = await g(`user:${pubkey}`); - let user = await g(`user:${id}`); - return ( - user || { - username: pubkey.substr(0, 6), - pubkey, - anon: true, - } - ); -}; - -function send(ev, url, opts) { - let timeout = (opts && opts.timeout != null && opts.timeout) || 1000; - - return new Promise((resolve, reject) => { - let relay = Relay(url); - - function timeout_reached() { - relay.close(); - reject(new Error("Request timeout")); - } - - let timer = setTimeout(timeout_reached, timeout); - - relay.on("open", () => { - clearTimeout(timer); - timer = setTimeout(timeout_reached, timeout); - relay.send(["EVENT", ev]); - }); - - relay.on("ok", (evid, ok, msg) => { - clearTimeout(timer); - relay.close(); - resolve({ evid, ok, msg }); - }); - }); -} - -export async function handleZap(invoice) { - let { data: privkey } = nip19.decode(config.nostrKey); - let pubkey = getPublicKey(privkey); - let keypair = { privkey, pubkey }; - let zapreq = JSON.parse(invoice.description); - - if (!zapreq.tags || zapreq.tags.length === 0) { - fail(`No tags found`); - } - - let ptags = zapreq.tags.filter( - (t) => t && t.length && t.length >= 2 && t[0] === "p", - ); - - if (ptags.length !== 1) { - fail(`None or multiple p tags found`); - } - - let etags = zapreq.tags.filter( - (t) => t && t.length && t.length >= 2 && t[0] === "e", - ); - - if (!(etags.length === 0 || etags.length === 1)) { - fail(`Expected none or 1 e tags`); - } - - let relays_tag = zapreq.tags.find( - (t) => t && t.length && t.length >= 2 && t[0] === "relays", - ); - - if (!relays_tag) { - fail(`No relays tag found`); - } - - let relays = relays_tag.slice(1).filter((r) => r && r.startsWith("ws")); - let etag = etags.length > 0 && etags[0]; - let ptag = ptags[0]; - - let kind = 9735; - let created_at = invoice.paid_at; - let content = zapreq.content; - - let tags = [ptag]; - if (etag) tags.push(etag); - - tags.push(["bolt11", invoice.bolt11]); - tags.push(["description", invoice.description]); - tags.push(["preimage", invoice.payment_preimage]); - - let ev = { pubkey, kind, created_at, content, tags }; - ev.id = await calculateId(ev); - ev.sig = await signId(privkey, ev.id); - - l("sending receipt"); - - await Promise.allSettled(relays.map((r) => send(ev, r))); -} - -// let damus = new Relay("ws://strfry:7777"); -// damus.on("open", (relay) => { -// damus.subscribe("nwc", { limit: 1, kinds: [23194] }); -// }); -// -// damus.on("event", async (sub, ev) => { -// console.log("EV", ev); -// }); |
