From 13c50c71bd2464a6c54bfaa975740197798c2fc3 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 22 Jan 2024 12:42:39 -0600 Subject: [PATCH] Cache the LNURL response --- src/deps.ts | 1 + src/pipeline.ts | 7 ++++--- src/utils/lnurl.ts | 24 ++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/deps.ts b/src/deps.ts index e76c84a5..bf23f9e1 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -88,6 +88,7 @@ export { default as stringifyStable } from 'npm:fast-stable-stringify@^1.0.0'; export { default as Debug } from 'npm:debug@^4.3.4'; export { LNURL, + type LNURLDetails, type MapCache, NIP05, } from 'https://gitlab.com/soapbox-pub/nlib/-/raw/137af48cbc2639a8969d233fc24d2b959f34782a/mod.ts'; diff --git a/src/pipeline.ts b/src/pipeline.ts index ad12b09e..7ec7c18e 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -1,8 +1,9 @@ import { Conf } from '@/config.ts'; +import { encryptAdmin } from '@/crypto.ts'; import { addRelays } from '@/db/relays.ts'; import { deleteAttachedMedia } from '@/db/unattached-media.ts'; import { findUser } from '@/db/users.ts'; -import { Debug, type Event, LNURL } from '@/deps.ts'; +import { Debug, type Event } from '@/deps.ts'; import { isEphemeralKind } from '@/kinds.ts'; import { isLocallyFollowed } from '@/queries.ts'; import { lnurlCallbackResponseSchema } from '@/schemas/lnurl.ts'; @@ -16,7 +17,7 @@ import { fetchWorker } from '@/workers/fetch.ts'; import { TrendsWorker } from '@/workers/trends.ts'; import { verifySignatureWorker } from '@/workers/verify.ts'; import { signAdminEvent } from '@/sign.ts'; -import { encryptAdmin } from '@/crypto.ts'; +import { lnurlCache } from '@/utils/lnurl.ts'; const debug = Debug('ditto:pipeline'); @@ -169,7 +170,7 @@ async function submitZaps(event: Event, data: EventData, signal = AbortSignal.ti const amount = event.tags.find(([name]) => name === 'amount')?.[1]; if (lnurl && amount) { try { - const details = await LNURL.lookup(lnurl, { fetch: fetchWorker, signal }); + const details = await lnurlCache.fetch(lnurl, { signal }); if (details.tag === 'payRequest' && details.allowsNostr && details.nostrPubkey) { const callback = new URL(details.callback); const params = new URLSearchParams(); diff --git a/src/utils/lnurl.ts b/src/utils/lnurl.ts index d2b4e964..07aae1d2 100644 --- a/src/utils/lnurl.ts +++ b/src/utils/lnurl.ts @@ -1,4 +1,24 @@ -import { LNURL } from '@/deps.ts'; +import { Debug, LNURL, type LNURLDetails } from '@/deps.ts'; +import { SimpleLRU } from '@/utils/SimpleLRU.ts'; +import { Time } from '@/utils/time.ts'; +import { fetchWorker } from '@/workers/fetch.ts'; + +const debug = Debug('ditto:lnurl'); + +const lnurlCache = new SimpleLRU( + async (lnurl, { signal }) => { + debug(`Lookup ${lnurl}`); + try { + const result = await LNURL.lookup(lnurl, { fetch: fetchWorker, signal }); + debug(`Found: ${lnurl}`); + return result; + } catch (e) { + debug(`Not found: ${lnurl}`); + throw e; + } + }, + { max: 1000, ttl: Time.minutes(30) }, +); /** Get an LNURL from a lud06 or lud16. */ function getLnurl({ lud06, lud16 }: { lud06?: string; lud16?: string }, limit?: number): string | undefined { @@ -12,4 +32,4 @@ function getLnurl({ lud06, lud16 }: { lud06?: string; lud16?: string }, limit?: } } -export { getLnurl }; +export { getLnurl, lnurlCache };