diff options
| author | Adam Soltys <[email protected]> | 2025-01-21 23:28:00 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-01-21 23:28:00 -0800 |
| commit | 9662c2754834599a1074d12565279674c20af467 (patch) | |
| tree | 1d77aaedf19b035378236305af582c903e025467 /lib | |
| parent | eb4e16b5599e67a65962db2a07629dfdcdda57dc (diff) | |
| download | coinos-server-9662c2754834599a1074d12565279674c20af467.tar.gz coinos-server-9662c2754834599a1074d12565279674c20af467.zip | |
notes and stuff
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/lightning.ts | 12 | ||||
| -rw-r--r-- | lib/nostr.ts | 38 | ||||
| -rw-r--r-- | lib/nwc.ts | 2 | ||||
| -rw-r--r-- | lib/payments.ts | 2 | ||||
| -rw-r--r-- | lib/strfry.ts | 39 |
5 files changed, 74 insertions, 19 deletions
diff --git a/lib/lightning.ts b/lib/lightning.ts index 19f6949d..3888a405 100644 --- a/lib/lightning.ts +++ b/lib/lightning.ts @@ -3,7 +3,7 @@ import ln from "$lib/ln"; import { err, warn } from "$lib/logging"; import { handleZap } from "$lib/nostr"; import { credit, types } from "$lib/payments"; -import { getPayment } from "$lib/utils"; +import { getPayment, getUser } from "$lib/utils"; export async function listenForLightning() { const inv = await ln.waitanyinvoice((await g("pay_index")) || 0); @@ -35,7 +35,10 @@ export async function listenForLightning() { if (invoice?.memo) { try { - if (JSON.parse(description).kind === 9734) handleZap(inv); + if (JSON.parse(description).kind === 9734) { + const { pubkey } = await getUser(invoice.uid); + handleZap(inv, pubkey); + } } catch (e) { if (!e.message.includes("Unexpected")) warn("failed to handle zap", e.message); @@ -81,7 +84,10 @@ export async function replay(index) { if (invoice?.memo) { try { - if (JSON.parse(description).kind === 9734) handleZap(inv); + if (JSON.parse(description).kind === 9734) { + const { pubkey } = await getUser(invoice.uid); + handleZap(inv, pubkey); + } } catch (e) { if (!e.message.includes("Unexpected")) warn("failed to handle zap", e.message); diff --git a/lib/nostr.ts b/lib/nostr.ts index 190873e2..21c254e3 100644 --- a/lib/nostr.ts +++ b/lib/nostr.ts @@ -33,7 +33,7 @@ export async function send(ev, url = config.nostr) { r.close(); } -export async function handleZap(invoice) { +export async function handleZap(invoice, sender = undefined) { try { const pubkey = serverPubkey; const sk = nip19.decode(config.nostrKey).data as Uint8Array; @@ -59,6 +59,10 @@ export async function handleZap(invoice) { fail("Expected none or 1 e tags"); } + const atags = zapreq.tags.filter( + (t) => t?.length && t.length >= 2 && t[0] === "a", + ); + const relays_tag = zapreq.tags.find( (t) => t?.length && t.length >= 2 && t[0] === "relays", ); @@ -69,6 +73,7 @@ export async function handleZap(invoice) { const relays = relays_tag.slice(1).filter((r) => r?.startsWith("ws")); const etag = etags.length > 0 && etags[0]; + const atag = atags.length > 0 && atags[0]; const ptag = ptags[0]; const kind = 9735; @@ -77,6 +82,8 @@ export async function handleZap(invoice) { const tags = [ptag]; if (etag) tags.push(etag); + if (atag) tags.push(atag); + if (sender) tags.push(["P", sender]); tags.push(["bolt11", invoice.bolt11]); tags.push(["description", invoice.description]); @@ -129,11 +136,10 @@ export const getProfile = async (pubkey) => { let profile = await g(`profile:${pubkey}`); if (profile) return profile; - const filter = { authors: [pubkey], kinds: [0] }; - const events = await scan(filter); + const event = await get({ authors: [pubkey], kinds: [0] }); - if (events.length) { - profile = JSON.parse(events[0].content); + if (event) { + profile = JSON.parse(event.content); } else { profile = anon(pubkey); } @@ -191,3 +197,25 @@ export const getNostrUser = async (key) => { return pick(user, fields); }; + +export const q = async (f) => { + const events = await scan(f); + 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; + }); + + if (events.length > 0) return events; + return p; +}; + +export const get = async (f) => { + f.limit = 1; + const events = await q(f); + return events[0]; +}; @@ -113,7 +113,7 @@ const handle = (method, params, user, ev) => inv.payment_preimage = preimage; inv.paid_at = Math.floor(Date.now() / 1000); try { - await handleZap(inv); + await handleZap(inv, pubkey); } catch (e) { console.log("zap receipt failed", e); } diff --git a/lib/payments.ts b/lib/payments.ts index 5f818ae4..1468a198 100644 --- a/lib/payments.ts +++ b/lib/payments.ts @@ -567,7 +567,7 @@ export const sendInternal = async ({ const inv = invoices[0]; inv.payment_preimage = p.id; inv.paid_at = Math.floor(Date.now() / 1000); - handleZap(inv).catch(console.log); + handleZap(inv, sender.pubkey).catch(console.log); } return p; diff --git a/lib/strfry.ts b/lib/strfry.ts index 231e3533..926ca429 100644 --- a/lib/strfry.ts +++ b/lib/strfry.ts @@ -1,9 +1,10 @@ import { randomUUID } from "crypto"; import { connect, createServer } from "net"; +import type { Event } from "nostr-tools"; -const exec = async (cmd) => +const exec = async (cmd: string, data = ""): Promise<Event[]> => new Promise((resolve, reject) => { - const c = `/app/strfry ${cmd} 2>/dev/null`; + const c = `${cmd} 2>/dev/null`; const id = randomUUID(); const resultSocketPath = `/sockets/result_${id}`; @@ -11,8 +12,8 @@ const exec = async (cmd) => let resultBuffer = ""; const results = []; - socket.on("data", (data) => { - resultBuffer += data.toString(); + socket.on("data", (chunk) => { + resultBuffer += chunk.toString(); const parts = resultBuffer.split("\n"); for (let i = 0; i < parts.length - 1; i++) { @@ -20,7 +21,7 @@ const exec = async (cmd) => const parsedObject = JSON.parse(parts[i]); results.push(parsedObject); } catch (e) { - console.error(parts[i]); + console.error("Failed to parse:", parts[i]); } } @@ -38,7 +39,8 @@ const exec = async (cmd) => resultServer.listen(resultSocketPath, () => { const controlClient = connect("/sockets/ctrl", () => { - const message = `${resultSocketPath} ${c}\n`; + // Send the command and data payload + const message = `${resultSocketPath} ${c}\n${data}\n`; controlClient.write(message); controlClient.end(); }); @@ -53,7 +55,26 @@ const exec = async (cmd) => }); }); -export const count = (f) => exec(`scan --count '${JSON.stringify(f)}'\n`); -export const scan = (f) => exec(`scan '${JSON.stringify(f)}'\n`); +// 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}' | /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(`sync ${r} --dir down --filter '${JSON.stringify(f)}'\n`); + exec(`/app/strfry sync ${r} --dir down --filter '${JSON.stringify(f)}'\n`); |
