diff options
| author | Adam Soltys <[email protected]> | 2024-10-08 20:13:48 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-10-10 12:17:05 -0700 |
| commit | 0a2734dfb5ae312f5283f93ab2e3f819ace3f94b (patch) | |
| tree | 9170fc9bb3c7e9bb5b05ccea407321eb6c7302ef /routes | |
| parent | 372c635714f6e7de8a0da135980697b49f207f2c (diff) | |
| download | coinos-server-0a2734dfb5ae312f5283f93ab2e3f819ace3f94b.tar.gz coinos-server-0a2734dfb5ae312f5283f93ab2e3f819ace3f94b.zip | |
nostr revamp wip
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/nostr.ts | 220 | ||||
| -rw-r--r-- | routes/users.ts | 20 |
2 files changed, 82 insertions, 158 deletions
diff --git a/routes/nostr.ts b/routes/nostr.ts index d3c293c6..0fce9bdc 100644 --- a/routes/nostr.ts +++ b/routes/nostr.ts @@ -1,6 +1,15 @@ -import { bail, nada, getUser, uniq } from "$lib/utils"; -import { g, db } from "$lib/db"; -import { pool, q, serverPubkey } from "$lib/nostr"; +import config from "$config"; +import { bail, chunk, getUser, uniq } from "$lib/utils"; +import { g, s, db } from "$lib/db"; +import { send, getRelays, serverPubkey, pool } from "$lib/nostr"; + +let anon = (pubkey) => ({ + username: pubkey.substr(0, 6), + pubkey, + anon: true, + follows: [], + followers: [], +}); export default { async event(req, res) { @@ -12,91 +21,8 @@ export default { let { pubkey } = event; - event.user = (await g(`user:${pubkey}`)) || { - username: pubkey.substr(0, 6), - pubkey, - anon: true, - follows: [], - followers: [], - }; - - res.send(event); - }, - - async notes(req, res) { - let { - params: { pubkey }, - } = req; - let user = await getUser(pubkey); - - if (!user) - user = { - username: pubkey.substr(0, 6), - pubkey, - anon: true, - follows: [], - followers: [], - }; - - let params = { - kinds: [1], - authors: [pubkey], - }, - opts = { since: 0 }; - - q(`${pubkey}:notes`, params, opts).catch(nada); - - let ids = await db.sMembers(pubkey); - - let events = ids.length - ? (await db.mGet(ids.map((k) => "ev:" + k))).map(JSON.parse) - : []; - - res.send(events.map((e) => ({ ...e, user }))); - }, - - async messages(req, res) { - let { - params: { pubkey, since = 0 }, - } = req; - let params = { - kinds: [4], - authors: [pubkey], - }; - - let opts = { since }; - - await q(`${pubkey}:messages`, params, opts).catch(nada); - - params = { - kinds: [4], - "#p": [pubkey], - }; - - await q(`${pubkey}:messages`, params, opts).catch(nada); - - let messages = await db.sMembers(`${pubkey}:messages`); - - messages = await Promise.all( - messages.map(async (id) => { - let m = await g(`ev:${id}`); + event.user = (await g(`user:${pubkey}`)) || anon(pubkey); - let aid = await g(`user:${m.pubkey}`); - m.author = await g(`user:${aid}`); - - let rid = await g(`user:${m.tags[0][1]}`); - m.recipient = await g(`user:${rid}`); - - return m; - }), - ); - - res.send(messages); - }, - - async broadcast(req, res) { - let { event } = req.body; - pool.send(["EVENT", event]); res.send(event); }, @@ -106,54 +32,70 @@ export default { query: { tagsonly }, } = req; try { - let sub = `${pubkey}:follows`, - params = { - limit: 1, - kinds: [3], - authors: [pubkey], - }, - opts = { timeout: 60000, eager: 60000 }; - - q(sub, params, opts).catch(nada); + let { relays } = config; + ({ write: relays } = await getRelays(pubkey)); - let tags = (await g(`${pubkey}:follows`)) || []; - if (tagsonly) return res.send(tags); + let ev = await pool.get([config.nostr], { + kinds: [3], + authors: [pubkey], + }); + if (!ev) { + pool + .get(relays, { + kinds: [3], + authors: [pubkey], + }) + .then(send); + } + let created_at; let follows = []; + let tags = []; + if (ev) ({ created_at, tags } = ev); + if (!tags.length || tagsonly) return res.send(tags); - console.log("L", tags.length); + let cache = await g(`${pubkey}:follows`); + if (cache && cache.t >= created_at) ({ follows } = cache); + else { + let profiles = []; + let pubkeys = tags.map((t) => t[1]).filter((p) => p.length === 64); + for (let authors of chunk(pubkeys, 100)) { + let filter = { authors, kinds: [0] }; + profiles.push(...(await pool.querySync([config.nostr], filter))); + } - for (let f of tags) { - let [_, pubkey] = f; - let user = await getUser(pubkey); + for (let p of profiles) { + let { content, pubkey } = p; + let user = JSON.parse(content); - if (!(user && user.updated)) { - console.log("Q", pubkey) - q(`${pubkey}:profile:f1`, { - limit: 1, - kinds: [0], - authors: [pubkey], - }).catch(nada); - } + let cache = await g(`${pubkey}:followers`); + let followers; + if (cache && cache.t >= created_at) ({ followers } = cache); + else { + let filter = { "#p": [pubkey], kinds: [3] }; + followers = await pool.querySync([config.nostr], filter); + s(`${pubkey}:followers`, { followers, t: created_at }); + } - if (!user) { - user = { - username: pubkey.substr(0, 6), - pubkey, - anon: true, - }; + user.followers = followers.length; + user.pubkey = pubkey; + follows.push(user); } - follows.push(user); - } + let followKeys = follows.map((f) => f.pubkey); + let missing = pubkeys + .filter((p) => !followKeys.includes(p)) + .map((pubkey) => anon(pubkey)); - follows = uniq(follows, (e) => e.pubkey); - follows.sort( - (a, b) => a.username && a.username.localeCompare(b.username), - ); + follows.sort((a: any, b: any) => b.followers - a.followers); + follows.push(...missing); + + s(`${pubkey}:follows`, { follows, t: created_at }); + } res.send(follows); } catch (e) { + console.log("follows fail", e); bail(res, e.message); } }, @@ -163,38 +105,10 @@ export default { params: { pubkey }, } = req; try { - let pubkeys = [ - ...new Set([...(await db.sMembers(`${pubkey}:followers`))]), - ]; - - let followers = []; - - q( - `${pubkey}:followers`, - { kinds: [3], "#p": [pubkey] }, - { timeout: 60000, eager: 60000 }, - ).catch(nada); + let pubkeys: any = await q({ "#p": [pubkey] }); + pubkeys = pubkeys.map((e) => e.pubkey); - for (let pubkey of pubkeys) { - let user = await getUser(pubkey); - - if (!user?.updated) { - q(`${pubkey}:profile:f2`, { - limit: 1, - kinds: [0], - authors: [pubkey], - }).catch(nada); - } - - if (!user) - user = { - username: pubkey.substr(0, 6), - pubkey, - anon: true, - }; - - followers.push(user); - } + let followers: any = await q({ authors: [pubkeys], kinds: [0] }); followers = uniq(followers, (e) => e.pubkey); followers.sort( diff --git a/routes/users.ts b/routes/users.ts index 18ef7e3b..f907340e 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -15,7 +15,7 @@ import { mail, templates } from "$lib/mail"; import upload from "$lib/upload"; import rpc from "@coinos/rpc"; import { nip19 } from "nostr-tools"; -import { hex } from "@scure/base"; +import { getProfile } from "$lib/nostr"; export default { upload, @@ -78,19 +78,27 @@ export default { try { if (key.startsWith("npub")) { try { - key = hex.encode(nip19.decode(key).data as Uint8Array); + key = nip19.decode(key).data; } catch (e) {} } let user = await getUser(key); - if (!user && key.length === 64) { + if (key.length === 64) { + let nostr: any = await getProfile(key); + if (nostr) { + nostr.username = nostr.name; + nostr.display = nostr.display_name || nostr.displayName; + } + + if (user) user.anon = false; + user = { + ...nostr, currency: "USD", - username: key, - display: key.substr(0, 6), pubkey: key, anon: true, + ...user, }; } @@ -105,8 +113,10 @@ export default { "display", "id", "hidepay", + "lud16", "memoPrompt", "npub", + "picture", "profile", "prompt", "pubkey", |
