aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/nostr.js44
-rw-r--r--lib/utils.js3
-rw-r--r--routes/events.js5
-rw-r--r--routes/users.js54
4 files changed, 75 insertions, 31 deletions
diff --git a/lib/nostr.js b/lib/nostr.js
index 257bca9e..034a4aaa 100644
--- a/lib/nostr.js
+++ b/lib/nostr.js
@@ -41,32 +41,35 @@ pool.on("event", async (relay, sub, ev) => {
let newuser = {
username: pubkey.substr(0, 6),
pubkey,
- anon: true
+ anon: true,
+ follows: [],
+ followers: []
};
ev.user = JSON.parse(await redis.get(`user:${pubkey}`)) || newuser;
- if (!ev.user.initialized) {
- relay.subscribe("zero", {
- limit: 1,
- kinds: [0],
- authors: [pubkey]
- });
- }
+ relay.subscribe("zero", {
+ limit: 1,
+ kinds: [0],
+ authors: [pubkey]
+ });
- if (ev.kind === 1) {
- broadcast("event", ev);
- }
+ broadcast("event", ev);
}
} else if (sub === "zero") {
let { pubkey } = ev;
let newuser = {
username: pubkey.substr(0, 6),
pubkey,
- anon: true
+ anon: true,
+ follows: [],
+ followers: []
};
let user = JSON.parse(await redis.get(`user:${pubkey}`)) || newuser;
+
+ if (user.profileUpdated > ev.created_at) return;
+
if (parsed.name && user.username === pubkey.substr(0, 6))
user.username = parsed.name;
@@ -75,17 +78,30 @@ pool.on("event", async (relay, sub, ev) => {
user = {
...user,
...parsed,
- initialized: true
+ initialized: true,
+ profileUpdated: ev.created_at
};
await redis.set(`user:${pubkey}`, JSON.stringify(user));
+ await redis.set(`user:${user.username}`, JSON.stringify(user));
} else if (sub.includes("follows")) {
let pubkey = sub.split(":")[0];
await redis.set(`${pubkey}:follows`, JSON.stringify(ev.tags));
for (let f of ev.tags) {
- await redis.sAdd(`${f[1]}:followers`, pubkey);
+ let [_, followPubkey] = f;
+ pool.subscribe("zero", {
+ limit: 1,
+ kinds: [0],
+ authors: [followPubkey]
+ });
+ await redis.sAdd(`${followPubkey}:followers`, pubkey);
}
store.fetching[pubkey] = false;
+ } else if (sub.includes("followers")) {
+ let followed = sub.split(":")[0];
+ let { pubkey } = ev;
+ await redis.sAdd(`${followed}:followers`, pubkey);
+ store.fetching[pubkey] = false;
} else {
if (!relay.url.includes("coinos")) return;
diff --git a/lib/utils.js b/lib/utils.js
index 17283836..5355cc2c 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -10,6 +10,7 @@ import lnd from "$lib/lnd";
import ln from "$lib/ln";
import { coinos } from "$lib/nostr";
+
const { Op } = sequelize;
export const sleep = n => new Promise(r => setTimeout(r, n));
@@ -204,3 +205,5 @@ export const derivePayRequest = async ({ amount, memo, tip }) => {
await ln.invoice(value ? `${value}sat` : "any", new Date(), memo, 360)
).bolt11;
};
+
+export const uniq = (a, k) => [...new Map(a.map(x => [k(x), x])).values()];
diff --git a/routes/events.js b/routes/events.js
index 63189f70..3f42fead 100644
--- a/routes/events.js
+++ b/routes/events.js
@@ -23,7 +23,7 @@ app.get("/nostr/:pubkey", async (req, res) => {
});
}
- if (!user) user = { username: pubkey.substr(0, 6), pubkey, anon: true };
+ if (!user) user = { username: pubkey.substr(0, 6), pubkey, anon: true, follows: [], followers: [] };
let { since } = user;
@@ -33,6 +33,9 @@ app.get("/nostr/:pubkey", async (req, res) => {
authors: [pubkey]
});
+ coinos.subscribe(`${pubkey}:followers`, { since, kinds: [3], "#p": [pubkey] });
+
+
user.since = Math.round(Date.now() / 1000);
await redis.set(`user:${pubkey}`, JSON.stringify(user));
diff --git a/routes/users.js b/routes/users.js
index 7a01f25e..d19e42ea 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -3,7 +3,7 @@ import redis from "$lib/redis";
import config from "$config";
import store from "$lib/store";
import { auth, optionalAuth } from "$lib/passport";
-import { getUser, wait } from "$lib/utils";
+import { getUser, uniq, wait } from "$lib/utils";
import axios from "axios";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
@@ -99,9 +99,23 @@ app.get("/users/:username", async (req, res) => {
)
});
+ if (user) user = user.get({ plain: true });
+ else user = JSON.parse(await redis.get(`user:${username}`));
+
+ if (!user && username.length === 64) {
+ let newuser = {
+ username: username.substr(0, 6),
+ pubkey: username,
+ anon: true,
+ follows: [],
+ followers: []
+ };
+
+ user = JSON.parse(await redis.get(`user:${newuser.pubkey}`)) || newuser;
+ }
+
if (!user) return res.code(500).send("User not found");
- user = user.get({ plain: true });
let { pubkey } = user;
if (pubkey) {
@@ -125,6 +139,7 @@ app.get("/users/:username", async (req, res) => {
res.send(user);
} catch (e) {
+ console.log(e);
res.code(500).send(e.message);
}
});
@@ -668,15 +683,19 @@ app.post("/checkPassword", auth, async function(req, res) {
app.get("/:pubkey/follows", async (req, res) => {
try {
let { pubkey } = req.params;
- let follows = JSON.parse(await redis.get(`${pubkey}:follows`)) || [];
+ let tags = JSON.parse(await redis.get(`${pubkey}:follows`)) || [];
- if (follows.length) {
- follows = await db.User.findAll({
- where: { pubkey: follows.map(t => t[1]) }
- });
-
- res.send(follows);
+ let follows = [];
+ for (let f of tags) {
+ let [_, pubkey] = f;
+ let user = JSON.parse(await redis.get(`user:${pubkey}`));
+ if (user) follows.push(user);
}
+
+ follows = uniq(follows, e => e.pubkey);
+ follows.sort((a, b) => a.username.localeCompare(b.username));
+
+ res.send(follows);
} catch (e) {
console.log(e);
res.code(500).send(e.message);
@@ -686,15 +705,18 @@ app.get("/:pubkey/follows", async (req, res) => {
app.get("/:pubkey/followers", async (req, res) => {
try {
let { pubkey } = req.params;
- let followers = await redis.sMembers(`${pubkey}:followers`);
+ let pubkeys = await redis.sMembers(`${pubkey}:followers`);
- if (followers.length) {
- followers = await db.User.findAll({
- where: { pubkey: followers }
- });
-
- res.send(followers);
+ let followers = [];
+ for (let pubkey of pubkeys) {
+ let user = JSON.parse(await redis.get(`user:${pubkey}`));
+ if (user) followers.push(user);
}
+
+ followers = uniq(followers, e => e.pubkey);
+ followers.sort((a, b) => a.username.localeCompare(b.username));
+
+ res.send(followers);
} catch (e) {
console.log(e);
res.code(500).send(e.message);