aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-01-20 00:19:09 -0800
committerAdam Soltys <[email protected]>2025-01-20 00:19:09 -0800
commit263ffd68ec8051dfad47d20fcb1ab1ea22ade520 (patch)
treeb3d2db9cfd9b7b8a5f1fd328cf8b55d9196862ab
parenta55eb812c4ea6dc9573f2bdf40f058a1d3ba90ee (diff)
downloadcoinos-server-263ffd68ec8051dfad47d20fcb1ab1ea22ade520.tar.gz
coinos-server-263ffd68ec8051dfad47d20fcb1ab1ea22ade520.zip
nostr threads
-rw-r--r--index.ts2
-rw-r--r--lib/nostr.ts37
-rw-r--r--routes/nostr.ts57
-rw-r--r--routes/users.ts36
4 files changed, 98 insertions, 34 deletions
diff --git a/index.ts b/index.ts
index 3d5aba14..950ea183 100644
--- a/index.ts
+++ b/index.ts
@@ -59,6 +59,8 @@ app.post("/parseEvent", nostr.parse);
app.get("/zaps/:id", nostr.zaps);
app.post("/zap", auth, nostr.zap);
app.post("/zapRequest", auth, nostr.zapRequest);
+app.get("/thread/:id", nostr.thread);
+app.get("/firehose", nostr.firehose);
app.get("/info", payments.info);
app.post("/payments", auth, payments.create);
diff --git a/lib/nostr.ts b/lib/nostr.ts
index 4fb79dfd..190873e2 100644
--- a/lib/nostr.ts
+++ b/lib/nostr.ts
@@ -2,7 +2,7 @@ import config from "$config";
import { db, g, s } from "$lib/db";
import { l, warn } from "$lib/logging";
import { count, scan, sync } from "$lib/strfry";
-import { fail } from "$lib/utils";
+import { fail, fields, getUser, pick } from "$lib/utils";
import { finalizeEvent, getPublicKey, nip19 } from "nostr-tools";
import { AbstractSimplePool } from "nostr-tools/abstract-pool";
import { Relay } from "nostr-tools/relay";
@@ -156,3 +156,38 @@ export const getCount = async (pubkey) => {
console.log(e);
}
};
+
+export const getNostrUser = async (key) => {
+ let user = await getUser(key);
+
+ if (key.length === 64) {
+ const nostr: any = await getProfile(key);
+ if (nostr) {
+ nostr.username = nostr.name || key.substr(0, 6);
+ nostr.display = nostr.display_name || nostr.displayName;
+ nostr.display_name = undefined;
+ nostr.displayName = undefined;
+ nostr.name = undefined;
+ }
+
+ if (user) {
+ user.anon = false;
+ nostr.display = undefined;
+ }
+
+ user = {
+ ...nostr,
+ currency: "USD",
+ pubkey: key,
+ anon: true,
+ ...user,
+ };
+ }
+
+ if (!user) fail("User not found");
+
+ if (user.pubkey) user.npub = nip19.npubEncode(user.pubkey);
+ user.prompt = !!user.prompt;
+
+ return pick(user, fields);
+};
diff --git a/routes/nostr.ts b/routes/nostr.ts
index 7e3dfcc7..61e23c30 100644
--- a/routes/nostr.ts
+++ b/routes/nostr.ts
@@ -4,6 +4,7 @@ import ln from "$lib/ln";
import {
anon,
getCount,
+ getNostrUser,
getProfile,
getRelays,
send,
@@ -17,6 +18,7 @@ import type { Event } from "nostr-tools";
import { decode } from "nostr-tools/nip19";
import type { ProfilePointer } from "nostr-tools/nip19";
import { getZapEndpoint, makeZapRequest } from "nostr-tools/nip57";
+import { Relay } from "nostr-tools/relay";
export default {
async event(req, res) {
@@ -51,6 +53,61 @@ export default {
res.send({ parts, names });
},
+ async thread(req, res) {
+ try {
+ const { id } = req.params;
+ const relay = await Relay.connect("wss://relay.primal.net");
+
+ console.log("ID", id);
+ const event: Event = await new Promise((resolve) => {
+ const sub = relay.subscribe([{ ids: [id] }], {
+ async onevent(event) {
+ resolve(event);
+ },
+ oneose() {
+ sub.close();
+ },
+ });
+ });
+
+ const thread = [];
+
+ const root =
+ event.tags.find((tag) => tag[0] === "e" && tag[3] === "root")?.[1] ||
+ event.id;
+
+ await new Promise<void>((resolve) => {
+ const sub = relay.subscribe([{ kinds: [1], "#e": [root] }], {
+ async onevent(event) {
+ thread.push(event);
+ },
+ oneose() {
+ sub.close();
+ resolve();
+ },
+ });
+ });
+
+ for (const e of thread) {
+ e.author = await getNostrUser(e.pubkey);
+ console.log("AUTHOR", e.author);
+ e.parts = parseContent(e);
+ e.names = {};
+ for (const { type, value } of e.parts) {
+ if (type.includes("nprofile") || type.includes("npub")) {
+ const { name } = await getProfile(value.pubkey);
+ e.names[value.pubkey] = name;
+ }
+ }
+ }
+
+ res.send(thread);
+ } catch (e) {
+ console.log(e);
+ bail(res, e.message);
+ }
+ },
+
async zaps(req, res) {
try {
let { id } = req.params;
diff --git a/routes/users.ts b/routes/users.ts
index 4bc54bd6..9b0fd240 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -5,7 +5,7 @@ import { requirePin } from "$lib/auth";
import { db, g, s } from "$lib/db";
import { err, l, warn } from "$lib/logging";
import { mail, templates } from "$lib/mail";
-import { getProfile } from "$lib/nostr";
+import { getNostrUser, getProfile } from "$lib/nostr";
import { reconcile, types } from "$lib/payments";
import register from "$lib/register";
import { emit } from "$lib/sockets";
@@ -13,7 +13,7 @@ import upload from "$lib/upload";
import { bail, fail, fields, getUser, pick } from "$lib/utils";
import whitelist from "$lib/whitelist";
import rpc from "@coinos/rpc";
-import { bytesToHex, randomBytes } from "@noble/hashes/utils";
+import { randomBytes } from "@noble/hashes/utils";
import { $ } from "bun";
import jwt from "jsonwebtoken";
import { getPublicKey, nip19, verifyEvent } from "nostr-tools";
@@ -86,37 +86,7 @@ export default {
} catch (e) {}
}
- let user = await getUser(key);
-
- if (key.length === 64) {
- const nostr: any = await getProfile(key);
- if (nostr) {
- nostr.username = nostr.name || key.substr(0, 6);
- nostr.display = nostr.display_name || nostr.displayName;
- nostr.display_name = undefined;
- nostr.displayName = undefined;
- nostr.name = undefined;
- }
-
- if (user) {
- user.anon = false;
- nostr.display = undefined;
- }
-
- user = {
- ...nostr,
- currency: "USD",
- pubkey: key,
- anon: true,
- ...user,
- };
- }
-
- if (!user) return res.code(500).send("User not found");
-
- if (user.pubkey) user.npub = nip19.npubEncode(user.pubkey);
- user.prompt = !!user.prompt;
-
+ const user = await getNostrUser(key);
res.send(pick(user, fields));
} catch (e) {
err("problem getting user", e.message);