From a2656ef3f8118daf3c42b004879acbdf316ffd78 Mon Sep 17 00:00:00 2001 From: Nicolas Cantu Date: Sun, 28 Dec 2025 22:56:34 +0100 Subject: [PATCH] Fix: Replace pool.sub() with createSubscription() for nostr-tools 2.19.4 compatibility --- lib/articlePublisherHelpersPresentation.ts | 3 +- lib/articlePublisherHelpersVerification.ts | 11 ++-- lib/articleQueries.ts | 10 ++-- lib/contentDeliveryVerification.ts | 13 +++-- lib/nostr.ts | 9 ++-- lib/nostrPrivateMessages.ts | 7 +-- lib/nostrSubscription.ts | 4 +- lib/nostrZapVerification.ts | 4 +- lib/notifications.ts | 7 ++- lib/paymentPollingZapReceipt.ts | 10 ++-- lib/platformTracking.ts | 9 ++-- lib/platformTrackingQueries.ts | 11 ++-- lib/reviewRewardUpdate.ts | 4 +- lib/reviews.ts | 5 +- lib/seriesQueries.ts | 9 ++-- lib/sponsoring.ts | 8 +-- lib/zapAggregation.ts | 8 +-- types/nostr-tools-extended.ts | 59 +++++++++++++++++++--- 18 files changed, 116 insertions(+), 75 deletions(-) diff --git a/lib/articlePublisherHelpersPresentation.ts b/lib/articlePublisherHelpersPresentation.ts index 979d229..6ef7dbf 100644 --- a/lib/articlePublisherHelpersPresentation.ts +++ b/lib/articlePublisherHelpersPresentation.ts @@ -65,7 +65,8 @@ export function fetchAuthorPresentationFromPool( return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() - const sub = pool.sub([relayUrl], filters) + const { createSubscription } = require('@/types/nostr-tools-extended') + const sub = createSubscription(pool, [relayUrl], filters) const finalize = (value: import('@/types/nostr').AuthorPresentationArticle | null) => { if (resolved) { diff --git a/lib/articlePublisherHelpersVerification.ts b/lib/articlePublisherHelpersVerification.ts index 1be6f87..3811156 100644 --- a/lib/articlePublisherHelpersVerification.ts +++ b/lib/articlePublisherHelpersVerification.ts @@ -1,6 +1,7 @@ import { nostrService } from './nostr' import { getPrimaryRelaySync } from './config' import type { Event } from 'nostr-tools' +import { createSubscription } from '@/types/nostr-tools-extended' export function createMessageVerificationFilters(messageEventId: string, authorPubkey: string, recipientPubkey: string, articleId: string) { return [ @@ -33,7 +34,7 @@ export function handleMessageVerificationEvent( } export function setupMessageVerificationHandlers( - sub: import('@/types/nostr-tools-extended').SimplePoolWithSub['sub'] extends (...args: any[]) => infer R ? R : never, + sub: import('@/types/nostr-tools-extended').Subscription, messageEventId: string, articleId: string, recipientPubkey: string, @@ -69,7 +70,7 @@ export function setupMessageVerificationHandlers( } function createMessageVerificationSubscription( - pool: import('@/types/nostr-tools-extended').SimplePoolWithSub, + pool: import('nostr-tools').SimplePool, messageEventId: string, authorPubkey: string, recipientPubkey: string, @@ -77,11 +78,11 @@ function createMessageVerificationSubscription( ) { const filters = createMessageVerificationFilters(messageEventId, authorPubkey, recipientPubkey, articleId) const relayUrl = getPrimaryRelaySync() - return pool.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } function createVerificationPromise( - sub: import('@/types/nostr-tools-extended').SimplePoolWithSub['sub'] extends (...args: any[]) => infer R ? R : never, + sub: import('@/types/nostr-tools-extended').Subscription, messageEventId: string, articleId: string, recipientPubkey: string, @@ -121,7 +122,7 @@ export function verifyPrivateMessagePublished( } const sub = createMessageVerificationSubscription( - pool as import('@/types/nostr-tools-extended').SimplePoolWithSub, + pool, messageEventId, authorPubkey, recipientPubkey, diff --git a/lib/articleQueries.ts b/lib/articleQueries.ts index aaf1154..5db6056 100644 --- a/lib/articleQueries.ts +++ b/lib/articleQueries.ts @@ -1,12 +1,13 @@ import type { Event } from 'nostr-tools' import { nostrService } from './nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { SimplePool } from 'nostr-tools' +import { createSubscription } from '@/types/nostr-tools-extended' import type { Article } from '@/types/nostr' import { parseArticleFromEvent } from './nostrEventParsing' import { buildTagFilter } from './nostrTagSystem' import { getPrimaryRelaySync } from './config' -function createSeriesSubscription(poolWithSub: SimplePoolWithSub, seriesId: string, limit: number) { +function createSeriesSubscription(pool: SimplePool, seriesId: string, limit: number) { const filters = [ { ...buildTagFilter({ @@ -17,7 +18,7 @@ function createSeriesSubscription(poolWithSub: SimplePoolWithSub, seriesId: stri }, ] const relayUrl = getPrimaryRelaySync() - return poolWithSub.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } export function getArticlesBySeries(seriesId: string, timeoutMs: number = 5000, limit: number = 100): Promise { @@ -25,8 +26,7 @@ export function getArticlesBySeries(seriesId: string, timeoutMs: number = 5000, if (!pool) { throw new Error('Pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub - const sub = createSeriesSubscription(poolWithSub, seriesId, limit) + const sub = createSeriesSubscription(pool, seriesId, limit) return new Promise((resolve) => { const results: Article[] = [] diff --git a/lib/contentDeliveryVerification.ts b/lib/contentDeliveryVerification.ts index e34fe19..16175a3 100644 --- a/lib/contentDeliveryVerification.ts +++ b/lib/contentDeliveryVerification.ts @@ -1,5 +1,5 @@ import { nostrService } from './nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { createSubscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' import type { Event } from 'nostr-tools' @@ -40,7 +40,7 @@ function createContentDeliveryFilters(authorPubkey: string, recipientPubkey: str } function setupContentDeliveryHandlers( - sub: SimplePoolWithSub['sub'] extends (...args: any[]) => infer R ? R : never, + sub: import('@/types/nostr-tools-extended').Subscription, status: ContentDeliveryStatus, finalize: (result: ContentDeliveryStatus) => void, isResolved: () => boolean @@ -71,7 +71,7 @@ function setupContentDeliveryHandlers( } function createContentDeliverySubscription( - pool: SimplePoolWithSub, + pool: import('nostr-tools').SimplePool, authorPubkey: string, recipientPubkey: string, articleId: string, @@ -79,11 +79,11 @@ function createContentDeliverySubscription( ) { const filters = createContentDeliveryFilters(authorPubkey, recipientPubkey, articleId, messageEventId) const relayUrl = getPrimaryRelaySync() - return pool.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } function createContentDeliveryPromise( - sub: SimplePoolWithSub['sub'] extends (...args: any[]) => infer R ? R : never, + sub: import('@/types/nostr-tools-extended').Subscription, status: ContentDeliveryStatus ): Promise { return new Promise((resolve) => { @@ -122,8 +122,7 @@ export function verifyContentDelivery( return Promise.resolve(status) } - const poolWithSub = pool as SimplePoolWithSub - const sub = createContentDeliverySubscription(poolWithSub, authorPubkey, recipientPubkey, articleId, messageEventId) + const sub = createContentDeliverySubscription(pool, authorPubkey, recipientPubkey, articleId, messageEventId) return createContentDeliveryPromise(sub, status) } catch (error) { status.error = error instanceof Error ? error.message : 'Unknown error' diff --git a/lib/nostr.ts b/lib/nostr.ts index 5cac954..9f7cd94 100644 --- a/lib/nostr.ts +++ b/lib/nostr.ts @@ -1,7 +1,7 @@ import { Event, EventTemplate, finalizeEvent, nip19, SimplePool } from 'nostr-tools' import { hexToBytes } from 'nostr-tools/utils' import type { Article, NostrProfile } from '@/types/nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { createSubscription } from '@/types/nostr-tools-extended' import { parseArticleFromEvent } from './nostrEventParsing' import { getPrivateContent as getPrivateContentFromPool, @@ -83,7 +83,7 @@ class NostrService { } } - private createArticleSubscription(pool: SimplePoolWithSub, limit: number) { + private createArticleSubscription(pool: SimplePool, limit: number) { const filters = [ { ...buildTagFilter({ @@ -93,7 +93,7 @@ class NostrService { }, ] const relayUrl = getPrimaryRelaySync() - return pool.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } subscribeToArticles(callback: (article: Article) => void, limit: number = 100): () => void { @@ -109,8 +109,7 @@ class NostrService { throw new Error('Pool not initialized') } - const pool = this.pool as SimplePoolWithSub - const sub = this.createArticleSubscription(pool, limit) + const sub = this.createArticleSubscription(this.pool, limit) sub.on('event', (event: Event) => { try { diff --git a/lib/nostrPrivateMessages.ts b/lib/nostrPrivateMessages.ts index 5ee64fb..8aaf600 100644 --- a/lib/nostrPrivateMessages.ts +++ b/lib/nostrPrivateMessages.ts @@ -1,6 +1,5 @@ import { Event, nip04 } from 'nostr-tools' import { SimplePool } from 'nostr-tools' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' import { decryptArticleContent, type DecryptionKey } from './articleEncryption' import { getPrimaryRelaySync } from './config' @@ -40,7 +39,8 @@ export function getPrivateContent( return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() - const sub = (pool as SimplePoolWithSub).sub([relayUrl], createPrivateMessageFilters(eventId, publicKey, authorPubkey)) + const { createSubscription } = require('@/types/nostr-tools-extended') + const sub = createSubscription(pool, [relayUrl], createPrivateMessageFilters(eventId, publicKey, authorPubkey)) const finalize = (result: string | null) => { if (resolved) { @@ -116,7 +116,8 @@ export async function getDecryptionKey( return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() - const sub = (pool as SimplePoolWithSub).sub([relayUrl], createPrivateMessageFilters(eventId, recipientPublicKey, authorPubkey)) + const { createSubscription } = require('@/types/nostr-tools-extended') + const sub = createSubscription(pool, [relayUrl], createPrivateMessageFilters(eventId, recipientPublicKey, authorPubkey)) const finalize = (result: DecryptionKey | null) => { if (resolved) { diff --git a/lib/nostrSubscription.ts b/lib/nostrSubscription.ts index 10ae01f..f2d384f 100644 --- a/lib/nostrSubscription.ts +++ b/lib/nostrSubscription.ts @@ -1,7 +1,7 @@ import type { Event, Filter } from 'nostr-tools' import { SimplePool } from 'nostr-tools' import { getPrimaryRelaySync } from './config' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { createSubscription } from '@/types/nostr-tools-extended' /** * Subscribe to events with timeout @@ -15,7 +15,7 @@ export function subscribeWithTimeout( return new Promise((resolve) => { const resolved = { value: false } const relayUrl = getPrimaryRelaySync() - const sub = (pool as SimplePoolWithSub).sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) let timeoutId: NodeJS.Timeout | null = null const cleanup = () => { diff --git a/lib/nostrZapVerification.ts b/lib/nostrZapVerification.ts index 6cc6193..0422305 100644 --- a/lib/nostrZapVerification.ts +++ b/lib/nostrZapVerification.ts @@ -1,6 +1,6 @@ import type { Event } from 'nostr-tools' import { SimplePool } from 'nostr-tools' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { createSubscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' function createZapFilters(targetPubkey: string, targetEventId: string, userPubkey: string) { @@ -63,7 +63,7 @@ export function checkZapReceipt( return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() - const sub = (pool as SimplePoolWithSub).sub([relayUrl], createZapFilters(targetPubkey, targetEventId, userPubkey)) + const sub = createSubscription(pool, [relayUrl], createZapFilters(targetPubkey, targetEventId, userPubkey)) const finalize = (value: boolean) => { if (resolved) { diff --git a/lib/notifications.ts b/lib/notifications.ts index 51d0c4d..d5ea0e5 100644 --- a/lib/notifications.ts +++ b/lib/notifications.ts @@ -2,7 +2,7 @@ import type { Event } from 'nostr-tools' import { nostrService } from './nostr' import { zapVerificationService } from './zapVerification' import type { Notification } from '@/types/notifications' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { createSubscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' function createZapReceiptFilters(userPubkey: string) { @@ -48,7 +48,7 @@ async function buildPaymentNotification(event: Event, userPubkey: string): Promi } function registerZapSubscription( - sub: ReturnType, + sub: import('@/types/nostr-tools-extended').Subscription, userPubkey: string, onNotification: (notification: Notification) => void ) { @@ -84,9 +84,8 @@ export class NotificationService { } const filters = createZapReceiptFilters(userPubkey) - const poolWithSub = pool as SimplePoolWithSub const relayUrl = getPrimaryRelaySync() - const sub = poolWithSub.sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) registerZapSubscription(sub, userPubkey, onNotification) diff --git a/lib/paymentPollingZapReceipt.ts b/lib/paymentPollingZapReceipt.ts index 7ab4d9b..cc7cc95 100644 --- a/lib/paymentPollingZapReceipt.ts +++ b/lib/paymentPollingZapReceipt.ts @@ -7,7 +7,7 @@ export function parseZapAmount(event: import('nostr-tools').Event): number { return amountTag ? Math.floor(parseInt(amountTag, 10) / 1000) : 0 } -export function createZapReceiptSubscription(poolWithSub: import('@/types/nostr-tools-extended').SimplePoolWithSub, articlePubkey: string, articleId: string) { +export function createZapReceiptSubscription(pool: import('nostr-tools').SimplePool, articlePubkey: string, articleId: string) { const filters = [ { kinds: [9735], @@ -17,7 +17,8 @@ export function createZapReceiptSubscription(poolWithSub: import('@/types/nostr- }, ] const relayUrl = getPrimaryRelaySync() - return poolWithSub.sub([relayUrl], filters) + const { createSubscription } = require('@/types/nostr-tools-extended') + return createSubscription(pool, [relayUrl], filters) } export function handleZapReceiptEvent( @@ -33,7 +34,7 @@ export function handleZapReceiptEvent( } export function createZapReceiptPromise( - sub: import('@/types/nostr-tools-extended').SimplePoolWithSub['sub'] extends (...args: any[]) => infer R ? R : never, + sub: import('@/types/nostr-tools-extended').Subscription, amount: number, recipientPubkey: string ): Promise { @@ -70,8 +71,7 @@ export async function getZapReceiptId( return undefined } - const poolWithSub = pool as import('@/types/nostr-tools-extended').SimplePoolWithSub - const sub = createZapReceiptSubscription(poolWithSub, articlePubkey, articleId) + const sub = createZapReceiptSubscription(pool, articlePubkey, articleId) return createZapReceiptPromise(sub, amount, recipientPubkey) } catch (error) { console.error('Error getting zap receipt ID', { diff --git a/lib/platformTracking.ts b/lib/platformTracking.ts index 268fba8..9d91eec 100644 --- a/lib/platformTracking.ts +++ b/lib/platformTracking.ts @@ -21,10 +21,9 @@ export class PlatformTrackingService { if (!pool) { throw new Error('Pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub const { getPrimaryRelaySync } = await import('./config') const relayUrl = getPrimaryRelaySync() - const pubs = poolWithSub.publish([relayUrl], event) + const pubs = pool.publish([relayUrl], event) await Promise.all(pubs) } @@ -99,8 +98,7 @@ export class PlatformTrackingService { return new Promise((resolve) => { const deliveries: ContentDeliveryTracking[] = [] let resolved = false - const poolWithSub = pool as SimplePoolWithSub - const sub = createArticleDeliveriesSubscription(poolWithSub, articleId, this.platformPubkey) + const sub = createArticleDeliveriesSubscription(pool, articleId, this.platformPubkey) const finalize = () => { if (resolved) { @@ -143,8 +141,7 @@ export class PlatformTrackingService { return new Promise((resolve) => { const deliveries: ContentDeliveryTracking[] = [] let resolved = false - const poolWithSub = pool as SimplePoolWithSub - const sub = createRecipientDeliveriesSubscription(poolWithSub, recipientPubkey, this.platformPubkey) + const sub = createRecipientDeliveriesSubscription(pool, recipientPubkey, this.platformPubkey) const finalize = () => { if (resolved) { diff --git a/lib/platformTrackingQueries.ts b/lib/platformTrackingQueries.ts index 7b3d082..f7894bb 100644 --- a/lib/platformTrackingQueries.ts +++ b/lib/platformTrackingQueries.ts @@ -1,5 +1,6 @@ import { Event } from 'nostr-tools' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import { SimplePool } from 'nostr-tools' +import { createSubscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' import type { ContentDeliveryTracking } from './platformTrackingTypes' import { getTrackingKind } from './platformTrackingEvents' @@ -37,7 +38,7 @@ export function parseTrackingEvent(event: Event): ContentDeliveryTracking | null } } -export function createArticleDeliveriesSubscription(pool: SimplePoolWithSub, articleId: string, platformPubkey: string) { +export function createArticleDeliveriesSubscription(pool: SimplePool, articleId: string, platformPubkey: string) { const filters = [ { kinds: [getTrackingKind()], @@ -47,10 +48,10 @@ export function createArticleDeliveriesSubscription(pool: SimplePoolWithSub, art }, ] const relayUrl = getPrimaryRelaySync() - return pool.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } -export function createRecipientDeliveriesSubscription(pool: SimplePoolWithSub, recipientPubkey: string, platformPubkey: string) { +export function createRecipientDeliveriesSubscription(pool: SimplePool, recipientPubkey: string, platformPubkey: string) { const filters = [ { kinds: [getTrackingKind()], @@ -60,5 +61,5 @@ export function createRecipientDeliveriesSubscription(pool: SimplePoolWithSub, r }, ] const relayUrl = getPrimaryRelaySync() - return pool.sub([relayUrl], filters) + return createSubscription(pool, [relayUrl], filters) } diff --git a/lib/reviewRewardUpdate.ts b/lib/reviewRewardUpdate.ts index 5bfa5f2..7fc6b5a 100644 --- a/lib/reviewRewardUpdate.ts +++ b/lib/reviewRewardUpdate.ts @@ -8,8 +8,8 @@ export async function fetchOriginalReviewEvent(reviewId: string): Promise((resolve) => { let resolved = false - const sub = poolWithSub.sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) const finalize = (value: Event | null) => { if (resolved) { diff --git a/lib/reviews.ts b/lib/reviews.ts index 291422a..fd5f7ea 100644 --- a/lib/reviews.ts +++ b/lib/reviews.ts @@ -1,6 +1,5 @@ import type { Event } from 'nostr-tools' import { nostrService } from './nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' import type { Review } from '@/types/nostr' import { parseReviewFromEvent } from './nostrEventParsing' import { buildTagFilter } from './nostrTagSystem' @@ -33,13 +32,13 @@ export function getReviewsForArticle(articleId: string, timeoutMs: number = 5000 if (!pool) { throw new Error('Pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub const filters = buildReviewFilters(articleId) + const { createSubscription } = require('@/types/nostr-tools-extended') return new Promise((resolve) => { const results: Review[] = [] const relayUrl = getPrimaryRelaySync() - const sub = poolWithSub.sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) let finished = false const done = () => { diff --git a/lib/seriesQueries.ts b/lib/seriesQueries.ts index 29aab61..6ac352a 100644 --- a/lib/seriesQueries.ts +++ b/lib/seriesQueries.ts @@ -1,6 +1,5 @@ import type { Event } from 'nostr-tools' import { nostrService } from './nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' import type { Series } from '@/types/nostr' import { parseSeriesFromEvent } from './nostrEventParsing' import { buildTagFilter } from './nostrTagSystem' @@ -26,13 +25,13 @@ export function getSeriesByAuthor(authorPubkey: string, timeoutMs: number = 5000 if (!pool) { throw new Error('Pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub const filters = buildSeriesFilters(authorPubkey) + const { createSubscription } = require('@/types/nostr-tools-extended') return new Promise((resolve) => { const results: Series[] = [] const relayUrl = getPrimaryRelaySync() - const sub = poolWithSub.sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) let finished = false const done = () => { @@ -73,12 +72,12 @@ export function getSeriesById(seriesId: string, timeoutMs: number = 5000): Promi if (!pool) { throw new Error('Pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub const filters = buildSeriesByIdFilters(seriesId) + const { createSubscription } = require('@/types/nostr-tools-extended') return new Promise((resolve) => { const relayUrl = getPrimaryRelaySync() - const sub = poolWithSub.sub([relayUrl], filters) + const sub = createSubscription(pool, [relayUrl], filters) let finished = false const done = (value: Series | null) => { diff --git a/lib/sponsoring.ts b/lib/sponsoring.ts index 6902201..efb4fe8 100644 --- a/lib/sponsoring.ts +++ b/lib/sponsoring.ts @@ -1,10 +1,9 @@ import { nostrService } from './nostr' -import { SimplePoolWithSub } from '@/types/nostr-tools-extended' import type { Article } from '@/types/nostr' import { getPrimaryRelaySync } from './config' import { buildTagFilter, extractTagsFromEvent } from './nostrTagSystem' -function subscribeToPresentation(pool: SimplePoolWithSub, pubkey: string): Promise { +function subscribeToPresentation(pool: import('nostr-tools').SimplePool, pubkey: string): Promise { const filters = [ { ...buildTagFilter({ @@ -18,7 +17,8 @@ function subscribeToPresentation(pool: SimplePoolWithSub, pubkey: string): Promi return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() - const sub = pool.sub([relayUrl], filters) + const { createSubscription } = require('@/types/nostr-tools-extended') + const sub = createSubscription(pool, [relayUrl], filters) const finalize = (value: number) => { if (resolved) { @@ -53,7 +53,7 @@ export function getAuthorSponsoring(pubkey: string): Promise { return Promise.resolve(0) } - return subscribeToPresentation(pool as SimplePoolWithSub, pubkey) + return subscribeToPresentation(pool, pubkey) } /** diff --git a/lib/zapAggregation.ts b/lib/zapAggregation.ts index a8531a3..ec0ed3d 100644 --- a/lib/zapAggregation.ts +++ b/lib/zapAggregation.ts @@ -1,6 +1,6 @@ import type { Event } from 'nostr-tools' import { nostrService } from './nostr' -import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' +import type { Subscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' interface ZapAggregationFilter { @@ -42,17 +42,17 @@ export function aggregateZapSats(params: ZapAggregationFilter): Promise if (!pool) { throw new Error('Nostr pool not initialized') } - const poolWithSub = pool as SimplePoolWithSub const filters = buildFilters(params) const relay = getPrimaryRelaySync() const timeout = params.timeoutMs ?? 5000 + const { createSubscription } = require('@/types/nostr-tools-extended') - const sub = poolWithSub.sub([relay], filters) + const sub = createSubscription(pool, [relay], filters) return collectZap(sub, timeout) } function collectZap( - sub: ReturnType, + sub: Subscription, timeout: number ): Promise { return new Promise((resolve, reject) => { diff --git a/types/nostr-tools-extended.ts b/types/nostr-tools-extended.ts index beba9fa..d6a50ff 100644 --- a/types/nostr-tools-extended.ts +++ b/types/nostr-tools-extended.ts @@ -12,13 +12,58 @@ export interface Subscription { } /** - * Alias for SimplePool with typed sub method from nostr-tools definitions. - * In nostr-tools 2.x, SimplePool has a sub method but it's not properly typed. + * Type for SimplePool with subscribe method (for backward compatibility) + * Note: SimplePool already has subscribe method, this is just for type compatibility */ -export interface SimplePoolWithSub extends SimplePool { - sub(relays: string[], filters: Filter[]): Subscription -} +export type SimplePoolWithSub = SimplePool -export function hasSubMethod(pool: SimplePool): pool is SimplePoolWithSub { - return typeof (pool as any).sub === 'function' +/** + * Helper to create a subscription compatible with the old API + */ +export function createSubscription( + pool: SimplePool, + relays: string[], + filters: Filter[] +): Subscription { + const events: Event[] = [] + let eoseReceived = false + const eventCallbacks: Array<(event: Event) => void> = [] + const eoseCallbacks: Array<() => void> = [] + + const subscription = pool.subscribe( + relays, + filters[0] || {}, + { + onevent: (event: Event) => { + events.push(event) + eventCallbacks.forEach((cb) => cb(event)) + }, + oneose: () => { + eoseReceived = true + eoseCallbacks.forEach((cb) => cb()) + }, + } + ) + + const subscriptionWrapper: Subscription = { + on(event: 'event' | 'eose', callback: ((event: Event) => void) | (() => void)): void { + if (event === 'event') { + const eventCb = callback as (event: Event) => void + eventCallbacks.push(eventCb) + // Emit any events that were already received + events.forEach((e) => eventCb(e)) + } else if (event === 'eose') { + const eoseCb = callback as () => void + if (eoseReceived) { + eoseCb() + } else { + eoseCallbacks.push(eoseCb) + } + } + }, + unsub(): void { + subscription.close() + }, + } + return subscriptionWrapper }