From 2d2c991645f3b0ac7fb3ad88afdad0bb67c28b74 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 27 Dec 2022 22:51:33 -0800 Subject: follower endpoints --- lib/nostr.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++--------- lib/utils.js | 21 ++++++++++++++++++++ lib/whitelist.js | 2 ++ 3 files changed, 73 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/nostr.js b/lib/nostr.js index 477d2b12..257bca9e 100644 --- a/lib/nostr.js +++ b/lib/nostr.js @@ -5,6 +5,7 @@ import store from "$lib/store"; import redis from "$lib/redis"; const { relays } = await got("https://nostr.watch/relays.json").json(); + export const pool = RelayPool(relays); pool.on("open", relay => { @@ -12,11 +13,18 @@ pool.on("open", relay => { relay.subscribe("live", { limit: 1 }); }); -let coinos; +export let coinos; let seen = []; let timeout; pool.on("event", async (relay, sub, ev) => { try { + let parsed; + try { + parsed = JSON.parse(ev.content); + } catch (e) { + parsed = ev.content; + } + if (sub === "live") { let { pubkey } = ev; @@ -28,26 +36,59 @@ pool.on("event", async (relay, sub, ev) => { 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]); - ev.user = JSON.parse(await redis.get(`user:${pubkey}`)) || { + let newuser = { username: pubkey.substr(0, 6), pubkey, anon: true }; + ev.user = JSON.parse(await redis.get(`user:${pubkey}`)) || newuser; + + if (!ev.user.initialized) { + relay.subscribe("zero", { + limit: 1, + kinds: [0], + authors: [pubkey] + }); + } + if (ev.kind === 1) { broadcast("event", ev); } } + } else if (sub === "zero") { + let { pubkey } = ev; + let newuser = { + username: pubkey.substr(0, 6), + pubkey, + anon: true + }; + + let user = JSON.parse(await redis.get(`user:${pubkey}`)) || newuser; + if (parsed.name && user.username === pubkey.substr(0, 6)) + user.username = parsed.name; + + delete parsed.name; + + user = { + ...user, + ...parsed, + initialized: true + }; + + await redis.set(`user:${pubkey}`, 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); + } + store.fetching[pubkey] = false; } else { + if (!relay.url.includes("coinos")) return; + let pubkey = sub; clearTimeout(store.timeouts[pubkey]); diff --git a/lib/utils.js b/lib/utils.js index 46267dbd..2854fefc 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,4 @@ +import store from "$lib/store"; import config from "$config"; import db from "$db"; import sequelize from "@sequelize/core"; @@ -37,6 +38,26 @@ export const getUser = async (username, transaction) => { user.haspin = !!user.pin; + let { pubkey } = user; + + if (pubkey) { + store.fetching[pubkey] = true; + store.timeouts[pubkey] = setTimeout( + () => (store.fetching[pubkey] = false), + 500 + ); + + coinos.subscribe(`${pubkey}:follows`, { + limit: 1, + kinds: [3], + authors: [pubkey] + }); + + await wait(() => !store.fetching[pubkey], 100, 10); + user.follows = JSON.parse(await redis.get(`${pubkey}:follows`)); + user.followers = await redis.sMembers(`${pubkey}:followers`); + } + return user; }; diff --git a/lib/whitelist.js b/lib/whitelist.js index 5a9c0ba3..e78bc8e5 100644 --- a/lib/whitelist.js +++ b/lib/whitelist.js @@ -10,6 +10,8 @@ export default [ "currency", "email", "fiat", + "follows", + "followers", "haspin", "id", "index", -- cgit v1.2.3