diff options
| author | Adam Soltys <[email protected]> | 2023-11-30 15:34:45 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-11-30 15:34:45 -0800 |
| commit | a7322928c45848cfb9984454bf8ece6e3439c673 (patch) | |
| tree | 9b1031c31ee1f8160306ac66749afe0802f8aa54 /lib/nostr.js | |
| parent | acb93f29e83b35c0917d88ebbc62812e2dff989f (diff) | |
| download | coinos-server-a7322928c45848cfb9984454bf8ece6e3439c673.tar.gz coinos-server-a7322928c45848cfb9984454bf8ece6e3439c673.zip | |
zaps and emails
Diffstat (limited to 'lib/nostr.js')
| -rw-r--r-- | lib/nostr.js | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/lib/nostr.js b/lib/nostr.js index 604d207d..3a370aec 100644 --- a/lib/nostr.js +++ b/lib/nostr.js @@ -1,9 +1,10 @@ import config from "$config"; -import { Relay, RelayPool } from "nostr"; +import { Relay, RelayPool, calculateId, signId, getPublicKey } from "nostr"; import { broadcast, emit } from "$lib/sockets"; import store from "$lib/store"; import { g, s, db } from "$lib/db"; -import { nada, wait } from "$lib/utils"; +import { fail, nada, wait } from "$lib/utils"; +import { nip19 } from "nostr-tools"; export let coinos; export let pool; @@ -178,3 +179,86 @@ let getUser = async pubkey => { } ); }; + +function send(ev, url, opts) { + let timeout = (opts && opts.timeout != null && opts.timeout) || 1000; + + return new Promise((resolve, reject) => { + let relay = Relay(url); + + function timeout_reached() { + relay.close(); + reject(new Error("Request timeout")); + } + + let timer = setTimeout(timeout_reached, timeout); + + relay.on("open", () => { + clearTimeout(timer); + timer = setTimeout(timeout_reached, timeout); + relay.send(["EVENT", ev]); + }); + + relay.on("ok", (evid, ok, msg) => { + clearTimeout(timer); + relay.close(); + resolve({ evid, ok, msg }); + }); + }); +} + +export async function handleZap(invoice) { + let { nostrKey: privkey } = config; + let pubkey = getPublicKey(privkey); + let keypair = { privkey, pubkey }; + let zapreq = JSON.parse(invoice.description); + + if (!zapreq.tags || zapreq.tags.length === 0) { + fail(`No tags found`); + } + + let ptags = zapreq.tags.filter( + t => t && t.length && t.length >= 2 && t[0] === "p" + ); + + if (ptags.length !== 1) { + fail(`None or multiple p tags found`); + } + + let etags = zapreq.tags.filter( + t => t && t.length && t.length >= 2 && t[0] === "e" + ); + + if (!(etags.length === 0 || etags.length === 1)) { + fail(`Expected none or 1 e tags`); + } + + let relays_tag = zapreq.tags.find( + t => t && t.length && t.length >= 2 && t[0] === "relays" + ); + + if (!relays_tag) { + fail(`No relays tag found`); + } + + let relays = relays_tag.slice(1).filter(r => r && r.startsWith("ws")); + let etag = etags.length > 0 && etags[0]; + let ptag = ptags[0]; + + let kind = 9735; + let created_at = invoice.paid_at; + let content = zapreq.content; + + let tags = [ptag]; + if (etag) tags.push(etag); + + tags.push(["bolt11", invoice.bolt11]); + tags.push(["description", invoice.description]); + tags.push(["preimage", invoice.payment_preimage]); + + let ev = { pubkey, kind, created_at, content, tags }; + ev.id = await calculateId(ev); + ev.sig = await signId(privkey, ev.id); + + await Promise.all(relays.map(r => send(ev, r))); +} |
