mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import { NostrEvent, NSchema as n } from '@nostrify/nostrify';
|
|
import { Kysely } from 'kysely';
|
|
import { z } from 'zod';
|
|
|
|
import { DittoTables } from '@/db/DittoTables.ts';
|
|
import { getAmount } from '@/utils/bolt11.ts';
|
|
|
|
interface ScavengerEventOpts {
|
|
savedEvent: Promise<NostrEvent | undefined>;
|
|
kysely: Kysely<DittoTables>;
|
|
}
|
|
|
|
/** Consumes the event already stored in the database and uses it to insert into a new custom table, if eligible.
|
|
* Scavenger is organism that eats dead or rotting biomass, such as animal flesh or plant material. */
|
|
async function scavengerEvent({ savedEvent, kysely }: ScavengerEventOpts): Promise<void> {
|
|
const event = await savedEvent;
|
|
if (!event) return;
|
|
|
|
switch (event.kind) {
|
|
case 9735:
|
|
await handleEvent9735(kysely, event);
|
|
break;
|
|
}
|
|
}
|
|
|
|
async function handleEvent9735(kysely: Kysely<DittoTables>, event: NostrEvent) {
|
|
const zapRequestString = event?.tags?.find(([name]) => name === 'description')?.[1];
|
|
if (!zapRequestString) return;
|
|
const zapRequest = n.json().pipe(n.event()).optional().catch(undefined).parse(zapRequestString);
|
|
if (!zapRequest) return;
|
|
|
|
const amountSchema = z.coerce.number().int().nonnegative().catch(0);
|
|
const amount_millisats = amountSchema.parse(getAmount(event?.tags.find(([name]) => name === 'bolt11')?.[1]));
|
|
if (!amount_millisats || amount_millisats < 1) return;
|
|
|
|
const zappedEventId = zapRequest.tags.find(([name]) => name === 'e')?.[1];
|
|
if (!zappedEventId) return;
|
|
|
|
await kysely.insertInto('event_zaps').values({
|
|
receipt_id: event.id,
|
|
target_event_id: zappedEventId,
|
|
sender_pubkey: zapRequest.pubkey,
|
|
amount_millisats,
|
|
comment: zapRequest.content,
|
|
}).execute();
|
|
}
|
|
|
|
export { scavengerEvent };
|