aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-01-28 22:15:52 -0800
committerAdam Soltys <[email protected]>2025-01-28 22:15:52 -0800
commit972c2499fb508424a3a61125f3e45c2d06cfbb43 (patch)
tree9594199bd848e5e282a402a233db210237a4bda1 /lib
parent0b019a93a57f6f8fc9c3b9af8f003a61ebaee7de (diff)
downloadcoinos-server-972c2499fb508424a3a61125f3e45c2d06cfbb43.tar.gz
coinos-server-972c2499fb508424a3a61125f3e45c2d06cfbb43.zip
nostr work
Diffstat (limited to 'lib')
-rw-r--r--lib/nostr.ts30
-rw-r--r--lib/strfry.ts102
-rw-r--r--lib/utils.ts1
3 files changed, 45 insertions, 88 deletions
diff --git a/lib/nostr.ts b/lib/nostr.ts
index 0bb01521..4fb92b86 100644
--- a/lib/nostr.ts
+++ b/lib/nostr.ts
@@ -1,13 +1,15 @@
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 { scan } from "$lib/strfry";
import { fail, fields, getUser, pick } from "$lib/utils";
import { finalizeEvent, getPublicKey, nip19 } from "nostr-tools";
+import type { Event } from "nostr-tools";
import { AbstractSimplePool } from "nostr-tools/abstract-pool";
import { Relay } from "nostr-tools/relay";
export const EX = 60 * 60 * 24;
+const coinos = await Relay.connect(config.nostr);
export const serverPubkey = getPublicKey(
nip19.decode(config.nostrKey).data as Uint8Array,
@@ -158,7 +160,8 @@ export const getCount = async (pubkey) => {
if (follows === null) {
const result = await get({ authors: [pubkey], kinds: [3] });
follows = result ? result.tags.filter((t) => t[0] === "p").length : 0;
- if (follows?.length) await db.set(`${pubkey}:follows:n`, JSON.stringify(follows), { EX });
+ if (follows?.length)
+ await db.set(`${pubkey}:follows:n`, JSON.stringify(follows), { EX });
}
const k = `${pubkey}:followers:n`;
@@ -215,19 +218,28 @@ export const getNostrUser = async (key) => {
};
export const q = async (f) => {
- const events = await scan(f);
+ let events = (await scan(f)) as Event[];
const k = JSON.stringify(f).replace(/[^a-zA-Z0-9]/g, "");
const since = await g(`${k}:since}`);
if (since) f.since = since;
- const p = sync("wss://relay.primal.net", f).then(async () => {
- const r = await scan(f);
- if (r.length) await s(`${k}:since`, r[r.length - 1].created_at);
- return r;
+ const p = new Promise((resolve) => {
+ const r = [];
+ pool.subscribeMany(["wss://relay.primal.net"], [f], {
+ onevent(e) {
+ r.push(e);
+ coinos.publish(e);
+ },
+ oneose() {
+ resolve(r);
+ },
+ });
});
- if (events.length > 0) return events;
- return p;
+ if (events.length) return events;
+ events = (await p) as Event[];
+ if (events.length) db.set(`${k}:since`, events[events.length - 1].created_at);
+ return events;
};
export const get = async (f) => {
diff --git a/lib/strfry.ts b/lib/strfry.ts
index 65b77709..b2791e74 100644
--- a/lib/strfry.ts
+++ b/lib/strfry.ts
@@ -1,83 +1,29 @@
-import { randomUUID } from "crypto";
-import { connect, createServer } from "net";
+import * as net from "net";
import type { Event } from "nostr-tools";
-const exec = async (cmd: string, data = ""): Promise<Event[]> =>
- new Promise((resolve, reject) => {
- const c = `${cmd} 2>/dev/null`;
- const id = randomUUID();
- const resultSocketPath = `/sockets/result_${id}`;
-
- const resultServer = createServer((socket) => {
- let resultBuffer = "";
-
- const results = [];
- socket.on("data", (chunk) => {
- resultBuffer += chunk.toString();
- const parts = resultBuffer.split("\n");
-
- for (let i = 0; i < parts.length - 1; i++) {
- try {
- const parsedObject = JSON.parse(parts[i]);
- results.push(parsedObject);
- } catch (e) {
- console.error("Failed to parse:", parts[i]);
- }
- }
+const controlSocketPath = "/home/bun/app/data/sockets/strsrv.sock";
- resultBuffer = parts[parts.length - 1];
- });
-
- socket.on("end", () => {
- socket.write("DONE");
- resolve(results);
- socket.end();
-
- resultServer.close();
- });
- });
-
- resultServer.listen(resultSocketPath, () => {
- const controlClient = connect("/sockets/ctrl", () => {
- // Send the command and data payload
- const message = `${resultSocketPath} ${c}\n${data}\n`;
- controlClient.write(message);
- controlClient.end();
- });
-
- controlClient.on("error", (e) => {
- reject(`Control socket error: ${e.message}`);
+export const scan = (f: object): Promise<Event[]> =>
+ new Promise((resolve, reject) => {
+ const result = [];
+ const client = net
+ .createConnection(controlSocketPath)
+ .on("connect", () => {
+ client.write(`${JSON.stringify(f)}\n`);
+ })
+ .on("data", (data) => {
+ result.push(data);
+ })
+ .on("end", () => {
+ resolve(
+ Buffer.concat(result)
+ .toString("utf8")
+ .split("\n")
+ .filter((l) => l)
+ .map((l) => JSON.parse(l) as Event),
+ );
+ })
+ .on("error", (e) => {
+ reject(e.message);
});
- });
-
- resultServer.on("error", (e) => {
- reject(`Result server error: ${e.message}`);
- });
});
-
-// const filter2params = (f) => {
-// let r = "";
-//
-// const { limit, since, until } = f;
-//
-// if (limit) r += `-l ${limit} `;
-// if (since) r += `-s ${since} `;
-// if (until) r += `-u ${until} `;
-//
-// for (const k of f.kinds || []) r += `-k ${k} `;
-// for (const a of f.authors || []) r += `-a ${a} `;
-// for (const e of f["#e"] || []) r += `-e ${e} `;
-// for (const p of f["#p"] || []) r += `-p ${p} `;
-//
-// return r;
-// };
-
-export const load = (data) =>
- exec(
- `echo '${data.replace(/'/g, "'\\''")}' | /app/strfry import --no-verify\n`,
- );
-export const count = (f) =>
- exec(`/app/strfry scan --count '${JSON.stringify(f)}'\n`);
-export const scan = (f) => exec(`/app/strfry scan '${JSON.stringify(f)}'\n`);
-export const sync = (r, f) =>
- exec(`/app/strfry sync ${r} --dir down --filter '${JSON.stringify(f)}'\n`);
diff --git a/lib/utils.ts b/lib/utils.ts
index a0a831d9..79b95e62 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -2,7 +2,6 @@ import config from "$config";
import { g, s } from "$lib/db";
import locales from "$lib/locales/index";
import migrate from "$lib/migrate";
-import whitelist from "$lib/whitelist";
import { bytesToHex, randomBytes } from "@noble/hashes/utils";
import { getPublicKey } from "nostr";