pipeline: clean up zaps function
This commit is contained in:
parent
13c50c71bd
commit
c5e7b3bf0c
|
@ -91,6 +91,6 @@ export {
|
||||||
type LNURLDetails,
|
type LNURLDetails,
|
||||||
type MapCache,
|
type MapCache,
|
||||||
NIP05,
|
NIP05,
|
||||||
} from 'https://gitlab.com/soapbox-pub/nlib/-/raw/137af48cbc2639a8969d233fc24d2b959f34782a/mod.ts';
|
} from 'https://gitlab.com/soapbox-pub/nlib/-/raw/5d711597f3b2a163817cc1fb0f1f3ce8cede7cf7/mod.ts';
|
||||||
|
|
||||||
export type * as TypeFest from 'npm:type-fest@^4.3.0';
|
export type * as TypeFest from 'npm:type-fest@^4.3.0';
|
||||||
|
|
|
@ -3,10 +3,9 @@ import { encryptAdmin } from '@/crypto.ts';
|
||||||
import { addRelays } from '@/db/relays.ts';
|
import { addRelays } from '@/db/relays.ts';
|
||||||
import { deleteAttachedMedia } from '@/db/unattached-media.ts';
|
import { deleteAttachedMedia } from '@/db/unattached-media.ts';
|
||||||
import { findUser } from '@/db/users.ts';
|
import { findUser } from '@/db/users.ts';
|
||||||
import { Debug, type Event } from '@/deps.ts';
|
import { Debug, type Event, LNURL } from '@/deps.ts';
|
||||||
import { isEphemeralKind } from '@/kinds.ts';
|
import { isEphemeralKind } from '@/kinds.ts';
|
||||||
import { isLocallyFollowed } from '@/queries.ts';
|
import { isLocallyFollowed } from '@/queries.ts';
|
||||||
import { lnurlCallbackResponseSchema } from '@/schemas/lnurl.ts';
|
|
||||||
import { updateStats } from '@/stats.ts';
|
import { updateStats } from '@/stats.ts';
|
||||||
import { client, eventsDB, memorelay, reqmeister } from '@/storages.ts';
|
import { client, eventsDB, memorelay, reqmeister } from '@/storages.ts';
|
||||||
import { Sub } from '@/subs.ts';
|
import { Sub } from '@/subs.ts';
|
||||||
|
@ -39,7 +38,7 @@ async function handleEvent(event: Event): Promise<void> {
|
||||||
trackHashtags(event),
|
trackHashtags(event),
|
||||||
fetchRelatedEvents(event, data),
|
fetchRelatedEvents(event, data),
|
||||||
processMedia(event, data),
|
processMedia(event, data),
|
||||||
submitZaps(event, data),
|
payZap(event, data),
|
||||||
streamOut(event, data),
|
streamOut(event, data),
|
||||||
broadcast(event, data),
|
broadcast(event, data),
|
||||||
]);
|
]);
|
||||||
|
@ -163,34 +162,37 @@ function processMedia({ tags, pubkey }: Event, { user }: EventData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Submit zap requests to Lightning nodes (for local users only). */
|
/** Emit Nostr Wallet Connect event from zaps so users may pay. */
|
||||||
async function submitZaps(event: Event, data: EventData, signal = AbortSignal.timeout(5000)) {
|
async function payZap(event: Event, data: EventData, signal = AbortSignal.timeout(5000)) {
|
||||||
if (event.kind === 9734 && data.user) {
|
if (event.kind !== 9734 || !data.user) return;
|
||||||
|
|
||||||
const lnurl = event.tags.find(([name]) => name === 'lnurl')?.[1];
|
const lnurl = event.tags.find(([name]) => name === 'lnurl')?.[1];
|
||||||
const amount = event.tags.find(([name]) => name === 'amount')?.[1];
|
const amount = Number(event.tags.find(([name]) => name === 'amount')?.[1]);
|
||||||
if (lnurl && amount) {
|
|
||||||
|
if (!lnurl || !amount) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const details = await lnurlCache.fetch(lnurl, { signal });
|
const details = await lnurlCache.fetch(lnurl, { signal });
|
||||||
if (details.tag === 'payRequest' && details.allowsNostr && details.nostrPubkey) {
|
|
||||||
const callback = new URL(details.callback);
|
if (details.tag !== 'payRequest' || !details.allowsNostr || !details.nostrPubkey) {
|
||||||
const params = new URLSearchParams();
|
throw new Error('invalid lnurl');
|
||||||
params.set('amount', amount);
|
}
|
||||||
params.set('nostr', JSON.stringify(event));
|
|
||||||
params.set('lnurl', lnurl);
|
if (amount > details.maxSendable || amount < details.minSendable) {
|
||||||
callback.search = params.toString();
|
throw new Error('amount out of range');
|
||||||
const response = await fetchWorker(callback, { signal });
|
}
|
||||||
const json = await response.json();
|
|
||||||
const { pr } = lnurlCallbackResponseSchema.parse(json);
|
const { pr } = await LNURL.callback(
|
||||||
|
details.callback,
|
||||||
|
{ amount, nostr: event, lnurl },
|
||||||
|
{ fetch: fetchWorker, signal },
|
||||||
|
);
|
||||||
|
|
||||||
const nwcRequestEvent = await signAdminEvent({
|
const nwcRequestEvent = await signAdminEvent({
|
||||||
kind: 23194,
|
kind: 23194,
|
||||||
content: await encryptAdmin(
|
content: await encryptAdmin(
|
||||||
event.pubkey,
|
event.pubkey,
|
||||||
JSON.stringify({
|
JSON.stringify({ method: 'pay_invoice', params: { invoice: pr } }),
|
||||||
method: 'pay_invoice',
|
|
||||||
params: {
|
|
||||||
invoice: pr,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
created_at: nostrNow(),
|
created_at: nostrNow(),
|
||||||
tags: [
|
tags: [
|
||||||
|
@ -198,14 +200,12 @@ async function submitZaps(event: Event, data: EventData, signal = AbortSignal.ti
|
||||||
['e', event.id],
|
['e', event.id],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await handleEvent(nwcRequestEvent);
|
await handleEvent(nwcRequestEvent);
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debug('lnurl error:', e);
|
debug('lnurl error:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the event is being received in a timely manner. */
|
/** Determine if the event is being received in a timely manner. */
|
||||||
const isFresh = (event: Event): boolean => eventAge(event) < Time.seconds(10);
|
const isFresh = (event: Event): boolean => eventAge(event) < Time.seconds(10);
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { z } from '@/deps.ts';
|
|
||||||
|
|
||||||
const lnurlCallbackResponseSchema = z.object({
|
|
||||||
pr: z.string(),
|
|
||||||
routes: z.unknown().array(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export { lnurlCallbackResponseSchema };
|
|
Loading…
Reference in New Issue