diff options
| -rwxr-xr-x | bun.lockb | bin | 206855 -> 206864 bytes | |||
| -rw-r--r-- | index.ts | 21 | ||||
| -rw-r--r-- | lib/nostr.ts | 145 | ||||
| -rw-r--r-- | package.json | 6 | ||||
| -rw-r--r-- | routes/nostr.ts | 40 | ||||
| -rw-r--r-- | tsconfig.json | 3 |
6 files changed, 122 insertions, 93 deletions
| Binary files differ @@ -6,20 +6,23 @@ import { getLocations } from "$lib/locations"; import { catchUp } from "$lib/payments"; import { getFx } from "$lib/rates"; import { sendHeartbeat } from "$lib/sockets"; +import { fillPool } from "$lib/nostr"; import ecash from "$routes/ecash"; import email from "$routes/email"; import info from "$routes/info"; -import locations from "$routes/locations"; -import lnurl from "$routes/lnurl"; -import rates from "$routes/rates"; import invoices from "$routes/invoices"; import items from "$routes/items"; -import users from "$routes/users"; +import lnurl from "$routes/lnurl"; +import locations from "$routes/locations"; +import nostr from "$routes/nostr"; import payments from "$routes/payments"; +import rates from "$routes/rates"; import shopify from "$routes/shopify"; +import users from "$routes/users"; try { + fillPool(); getLocations(); getFx(); catchUp(); @@ -41,6 +44,14 @@ app.get("/locations", locations.list); app.get("/invoice/:id", invoices.get); app.post("/invoice", optional, invoices.create); +app.get("/nostr.json", nostr.identities); +app.get("/:pubkey/followers", nostr.followers); +app.get("/:pubkey/follows", nostr.follows); +app.get("/:pubkey/notes", nostr.notes); +app.get("/:pubkey/:since/messages", nostr.messages); +app.get("/event/:id", nostr.event); +app.post("/event", nostr.broadcast); + app.get("/info", payments.info); app.post("/payments", auth, payments.create); app.get("/payments", auth, payments.list); @@ -101,7 +112,7 @@ app.post("/shopify/:id", shopify); app.post("/hidepay", admin, users.hidepay); app.post("/unlimit", admin, users.unlimit); -app.get("/cash/:id", ecash.get); +app.get("/cash/:id/:version", ecash.get); app.post("/cash", ecash.save); app.post("/claim", auth, ecash.claim); app.post("/mint", auth, ecash.mint); diff --git a/lib/nostr.ts b/lib/nostr.ts index ccfb4e54..172e3ce0 100644 --- a/lib/nostr.ts +++ b/lib/nostr.ts @@ -1,11 +1,10 @@ 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 { fail, wait } from "$lib/utils"; import { nip19 } from "nostr-tools"; +import { emit } from "$lib/sockets"; export const COINOS_PUBKEY = getPublicKey(nip19.decode(config.nostrKey).data); export let coinos; @@ -13,91 +12,91 @@ 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 = 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; + pool.on("event", async (_, sub, ev) => { + if (!coinos && coinos.ws.readyState !== WebSocket.OPEN) return; + if (timeouts[sub]) timeouts[sub].extend(ev); try { - content = JSON.parse(ev.content); - } catch (e) { - content = ev.content; - } + let content; + try { + content = JSON.parse(ev.content); + } catch (e) { + content = ev.content; + } - if (sub === "live") { - let { pubkey } = ev; + if (sub === "live") { + let { pubkey } = ev; - if (Math.abs(Math.floor(Date.now() / 1000) - ev.created_at) > 7200) - return; + 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 (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 (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); + 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); + } else if (sub.includes("profile")) { + let { pubkey } = ev; + let user = await getUser(pubkey); - if (user.updated > ev.created_at) return; + if (user.updated > ev.created_at) return; - if (content.name && user.username === pubkey.substr(0, 6)) - user.username = content.name; + if (content.name && user.username === pubkey.substr(0, 6)) + user.username = content.name; - delete content.name; + delete content.name; - user = { - ...user, - ...content, - updated: ev.created_at, - }; + 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); + 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); } - 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(e); - } - }); - } catch(e) { - console.log("POOL", e) + }); + } catch (e) { + console.log("POOL", e); } }; diff --git a/package.json b/package.json index bd54dc30..b12e5fbc 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,13 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "node index.js", - "dev": "bun --stack-size=4096 --hot index.ts", + "start": "bun index.js", + "dev": "nodemon --exec bun index.ts", "format": "biome format *.js **/*.js --write" }, "dependencies": { "@aws-sdk/client-ses": "^3.449.0", - "@cashu/cashu-ts": "^1.0.1", + "@cashu/cashu-ts": "github:cashubtc/cashu-ts#development", "@fastify/cors": "^8.3.0", "@fastify/http-proxy": "^9.5.0", "@fastify/multipart": "^8.0.0", diff --git a/routes/nostr.ts b/routes/nostr.ts index fdfa2613..51b4e1ea 100644 --- a/routes/nostr.ts +++ b/routes/nostr.ts @@ -1,10 +1,12 @@ import { bail, nada, getUser, uniq } from "$lib/utils"; -import config from "$config"; -import { g, s, db } from "$lib/db"; -import { pool, q } from "$lib/nostr"; +import { g, db } from "$lib/db"; +import { pool, q, COINOS_PUBKEY } from "$lib/nostr"; export default { - async event({ params: { id } }, res) { + async event(req, res) { + let { + params: { id }, + } = req; let event = await g(`ev:${id}`); if (!event) return bail(res, "event not found"); @@ -21,7 +23,10 @@ export default { res.send(event); }, - async notes({ params: { pubkey } }, res) { + async notes(req, res) { + let { + params: { pubkey }, + } = req; let uid = await g(`user:${pubkey}`); let user = await g(`user:${uid}`); @@ -51,7 +56,10 @@ export default { res.send(events.map((e) => ({ ...e, user }))); }, - async messages({ params: { pubkey, since = 0 } }, res) { + async messages(req, res) { + let { + params: { pubkey, since = 0 }, + } = req; let params = { kinds: [4], authors: [pubkey], @@ -93,7 +101,11 @@ export default { res.send(event); }, - async follows({ params: { pubkey }, query: { tagsonly } }, res) { + async follows(req, res) { + let { + params: { pubkey }, + query: { tagsonly }, + } = req; try { let sub = `${pubkey}:follows`, params = { @@ -142,7 +154,10 @@ export default { } }, - async followers({ params: { pubkey } }, res) { + async followers(req, res) { + let { + params: { pubkey }, + } = req; try { let pubkeys = [ ...new Set([...(await db.sMembers(`${pubkey}:followers`))]), @@ -192,7 +207,10 @@ export default { } }, - async identities({ query: { name } }, res) { + async identities(req, res) { + let { + query: { name }, + } = req; let names = {}; if (name) { names = { [name]: (await getUser(name)).pubkey }; @@ -207,7 +225,7 @@ export default { res.send({ names }); }, - async info(req, res) { + async info(_, res) { res.send({ pubkey: COINOS_PUBKEY }); - } + }, }; diff --git a/tsconfig.json b/tsconfig.json index 60a23477..330e2915 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,8 @@ "paths": { "$lib/*": ["./lib/*.ts"], "$routes/*": ["./routes/*.ts"], - "$config": ["./config.ts"] + "$config": ["./config.ts"], + "@cashu/cashu-ts": ["node_modules/@cashu/cashu-ts/dist/lib/es6/index.js"] } } } |
