aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-12-20 17:39:28 -0800
committerAdam Soltys <[email protected]>2022-12-20 17:39:28 -0800
commitaa662369cc7a293d0be5f4d419543a51ad40a7bc (patch)
tree8b53bd0ead2be327a00632014672e6b73e1dab10
parent9ebd4105fa412d16bfe58facc9ebb53847b3316a (diff)
downloadcoinos-server-aa662369cc7a293d0be5f4d419543a51ad40a7bc.tar.gz
coinos-server-aa662369cc7a293d0be5f4d419543a51ad40a7bc.zip
send user events
-rw-r--r--index.js1
-rw-r--r--lib/nostr.js70
-rw-r--r--lib/store.js4
-rw-r--r--lib/utils.js8
-rw-r--r--routes/events.js30
-rw-r--r--routes/users.js2
6 files changed, 80 insertions, 35 deletions
diff --git a/index.js b/index.js
index c4c6ebc6..d83afd91 100644
--- a/index.js
+++ b/index.js
@@ -18,6 +18,7 @@ import "./lib/mail";
import "./lib/nostr";
import "./routes/assets";
+import "./routes/events";
import "./routes/locations";
import "./routes/info";
import "./routes/users";
diff --git a/lib/nostr.js b/lib/nostr.js
index b1b24b87..677f14e5 100644
--- a/lib/nostr.js
+++ b/lib/nostr.js
@@ -1,48 +1,52 @@
import { Relay, RelayPool } from "nostr";
import { got } from "got";
import { broadcast } from "$lib/sockets";
+import store from "$lib/store";
+import redis from "$lib/redis";
const { relays } = await got("https://nostr.watch/relays.json").json();
-const pool = RelayPool(relays);
+export const pool = RelayPool(relays);
let coinos;
-pool.on("open", (relay) => {
+pool.on("open", relay => {
if (relay.url.includes("coinos")) coinos = relay;
- relay.subscribe("subid", { limit: 1 });
+ relay.subscribe("live", { limit: 1 });
});
let seen = [];
-pool.on("event", (relay, sub_id, ev) => {
- if (seen.includes(ev.id)) return;
- if (Math.abs(Math.floor(Date.now()/1000) - ev.created_at) > 7200) return;
- seen.push(ev.id);
- seen.length > 1000 && seen.shift();
+let timeout;
+pool.on("event", async (relay, sub, ev) => {
+ try {
+ if (sub === "live") {
+ if (Math.abs(Math.floor(Date.now() / 1000) - ev.created_at) > 7200)
+ return;
- if (
- coinos &&
- ev.kind < 5 &&
- !ev.content.startsWith("test") &&
- !ev.content.startsWith("running branle")
- ) {
- let parsed;
- try {
- parsed = JSON.parse(ev.content);
- } catch (e) {
- parsed = ev.content;
- }
+ if (seen.includes(ev.id)) return;
+ seen.push(ev.id);
+ seen.length > 1000 && seen.shift();
+
+ if (coinos && ev.kind < 5) {
+ let parsed;
+ try {
+ parsed = JSON.parse(ev.content);
+ } catch (e) {
+ parsed = ev.content;
+ }
+
+ coinos.send(["EVENT", ev]);
+ if (ev.kind === 1) broadcast("event", ev);
+ }
+ } else {
+ let pubkey = sub;
+ clearTimeout(store.timeouts[pubkey]);
- coinos.send(["EVENT", ev]);
- if (ev.kind === 1)
- broadcast("event", ev);
+ store.fetching[pubkey] = true;
+ await redis.sAdd(pubkey, ev.id);
+ await redis.set(`ev:${ev.id}`, JSON.stringify(ev));
+
+ store.timeouts[pubkey] = setTimeout(() => (store.fetching[pubkey] = false), 100);
+ }
+ } catch (e) {
+ console.log(e);
}
});
-
-function formatDate(date) {
- var hours = date.getHours();
- var minutes = date.getMinutes();
- hours = hours % 12;
- hours = hours ? hours : 12;
- minutes = minutes < 10 ? "0" + minutes : minutes;
- var strTime = hours + ":" + minutes;
- return date.getMonth() + 1 + "/" + date.getDate() + " " + strTime;
-}
diff --git a/lib/store.js b/lib/store.js
index 6f2e47ce..f6f65521 100644
--- a/lib/store.js
+++ b/lib/store.js
@@ -20,5 +20,7 @@ export default {
bcAddressIndex: 0,
lqAddressIndex: 0,
last: {},
- payments: []
+ payments: [],
+ fetching: {},
+ timeouts: {},
};
diff --git a/lib/utils.js b/lib/utils.js
index 45e50243..7fdd10b3 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -171,3 +171,11 @@ export const derivePayRequest = async ({ amount, memo, tip }) => {
await ln.invoice(value ? `${value}sat` : "any", new Date(), memo, 360)
).bolt11;
};
+
+export const sleep = (n) => new Promise((r) => setTimeout(r, n));
+export const wait = async (f, s = 300, n = 1000) => {
+ let i = 0;
+ while (!(await f()) && i < s) (await sleep(n)) && i++;
+ if (i >= s) throw new Error("timeout");
+ return f();
+};
diff --git a/routes/events.js b/routes/events.js
new file mode 100644
index 00000000..460d09a5
--- /dev/null
+++ b/routes/events.js
@@ -0,0 +1,30 @@
+import app from "$app";
+import redis from "$lib/redis";
+import { pool } from "$lib/nostr";
+import store from "$lib/store";
+import { wait } from "$lib/utils";
+
+app.get("/:pubkey/events", async (req, res) => {
+ try {
+ let { pubkey } = req.params;
+ store.fetching[pubkey] = true;
+ store.timeouts[pubkey] = setTimeout(() => (store.fetching[pubkey] = false), 500);
+
+ pool.subscribe(pubkey, {
+ limit: 500,
+ kinds: [1],
+ authors: [pubkey]
+ });
+
+ let events = [];
+ await wait(() => !store.fetching[pubkey], 10, 10);
+ for (let id of await redis.sMembers(pubkey)) {
+ events.push(JSON.parse(await redis.get(`ev:${id}`)));
+ }
+
+ res.send(events);
+ } catch (e) {
+ console.log(e);
+ res.code(500).send("problem fetching user events");
+ }
+});
diff --git a/routes/users.js b/routes/users.js
index c4b613eb..8d45e8c3 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -56,7 +56,7 @@ app.get("/me", auth, async (req, res) => {
app.get("/users/:username", async (req, res) => {
const { username } = req.params;
- const user = await db.User.findOne({
+ let user = await db.User.findOne({
attributes: ["username", "banner", "profile", "address", "currency"],
where: Sequelize.where(
Sequelize.fn("lower", Sequelize.col("username")),