diff --git a/deploy.sh b/deploy.sh index a729e9d..adfa5b7 100644 --- a/deploy.sh +++ b/deploy.sh @@ -29,7 +29,7 @@ check_ssh_connection() { ssh_exec() { local max_retries=3 local retry_count=0 - + while [ $retry_count -lt $max_retries ]; do # Vérifier si la connexion maître existe et est valide if [ -S "${SSH_CONTROL_PATH}" ]; then @@ -38,7 +38,7 @@ ssh_exec() { cleanup_dead_ssh fi fi - + # Exécuter la commande SSH if ssh -o ControlMaster=auto \ -o ControlPath="${SSH_CONTROL_PATH}" \ @@ -51,7 +51,7 @@ ssh_exec() { else local exit_code=$? retry_count=$((retry_count + 1)) - + if [ $retry_count -lt $max_retries ]; then # Nettoyer la connexion morte avant de réessayer cleanup_dead_ssh diff --git a/docs/payment-notes-system.md b/docs/payment-notes-system.md new file mode 100644 index 0000000..77ca420 --- /dev/null +++ b/docs/payment-notes-system.md @@ -0,0 +1,345 @@ +# Payment Notes System + +**Author**: Équipe 4NK +**Date**: 2026-01-05 +**Status**: Implemented + +## Overview + +This document describes the implementation of explicit payment notes (kind 1) for all confirmed payments, in addition to zap receipts (kind 9735). These notes use the project's tag system and are automatically published after payment confirmation. + +## Motivations + +- **Transparency**: Provide explicit, searchable payment records on Nostr +- **Tag System Compliance**: All payment notes use the project's standardized tag system +- **Traceability**: Enable easy querying and aggregation of payments +- **User Experience**: Users can see their payment history in their Nostr feed + +## Root Causes + +- Zap receipts (kind 9735) are created by Lightning wallets and may not always include all project-specific tags +- Need for explicit payment records that follow the project's tag conventions +- Requirement to document all payment types (purchases, review tips, sponsoring) consistently + +## Implementation + +### 1. Tag System Extension + +#### New Payment Type + +Added `'payment'` to the `TagType` union in `lib/nostrTagSystemTypes.ts`: + +```typescript +export type TagType = 'author' | 'series' | 'publication' | 'quote' | 'payment' +``` + +#### PaymentTags Interface + +New interface for payment notes: + +```typescript +export interface PaymentTags extends BaseTags { + type: 'payment' + paymentType: 'purchase' | 'review_tip' | 'sponsoring' + amount: number + payerPubkey: string + recipientPubkey: string + paymentHash: string + zapReceiptId?: string + articleId?: string + reviewId?: string + seriesId?: string + text?: string +} +``` + +#### Tag Builder + +Added `buildPaymentTags` function in `lib/nostrTagSystemBuild.ts` to construct payment note tags: + +- `kind_type`: Payment type (purchase, review_tip, sponsoring) +- `amount`: Payment amount in sats +- `payer`: Payer's pubkey +- `recipient`: Recipient's pubkey +- `payment_hash`: Payment hash or transaction ID +- `zap_receipt`: Zap receipt ID (if applicable) +- `article`: Article ID (if applicable) +- `review_id`: Review ID (if applicable) +- `series`: Series ID (if applicable) +- `text`: Optional plain text message +- `transaction_id`: Bitcoin transaction ID (for sponsoring) + +### 2. Payment Notes Service + +New file `lib/paymentNotes.ts` contains three main functions: + +#### `publishPurchaseNote` + +Publishes an explicit payment note for article purchases. + +**Parameters**: +- `articleId`: Article ID +- `authorPubkey`: Author's pubkey +- `payerPubkey`: Payer's pubkey +- `amount`: Payment amount in sats +- `paymentHash`: Payment hash from zap receipt +- `zapReceiptId`: Zap receipt event ID (optional) +- `category`: Article category +- `seriesId`: Series ID (optional) +- `payerPrivateKey`: Payer's private key for signing + +**Process**: +1. Generates hash ID using `generatePurchaseHashId` +2. Builds object ID with `buildObjectId` +3. Constructs tags using `buildTags` with `PaymentTags` +4. Includes JSON metadata with full payment information +5. Publishes kind 1 event with payment confirmation message + +#### `publishReviewTipNote` + +Publishes an explicit payment note for review tips. + +**Parameters**: +- `articleId`: Article ID +- `reviewId`: Review ID +- `authorPubkey`: Author's pubkey +- `reviewerPubkey`: Reviewer's pubkey +- `payerPubkey`: Payer's pubkey +- `amount`: Payment amount in sats +- `paymentHash`: Payment hash from zap receipt +- `zapReceiptId`: Zap receipt event ID (optional) +- `category`: Article category +- `seriesId`: Series ID (optional) +- `text`: Optional plain text message +- `payerPrivateKey`: Payer's private key for signing + +**Process**: +1. Generates hash ID using `generateReviewTipHashId` +2. Builds object ID with `buildObjectId` +3. Constructs tags using `buildTags` with `PaymentTags` +4. Includes JSON metadata with full tip information +5. Publishes kind 1 event with tip confirmation message (includes text if provided) + +#### `publishSponsoringNote` + +Publishes an explicit payment note for sponsoring payments. + +**Parameters**: +- `authorPubkey`: Author's pubkey +- `payerPubkey`: Payer's pubkey +- `amount`: Payment amount in sats +- `paymentHash`: Payment hash or transaction ID +- `category`: Author category (optional) +- `seriesId`: Series ID (optional) +- `articleId`: Article ID (optional) +- `text`: Optional plain text message +- `transactionId`: Bitcoin transaction ID (optional) +- `payerPrivateKey`: Payer's private key for signing + +**Process**: +1. Generates hash ID using `generateSponsoringHashId` +2. Builds object ID with `buildObjectId` +3. Constructs tags using `buildTags` with `PaymentTags` +4. Adds `transaction_id` tag if provided (for Bitcoin mainnet payments) +5. Includes JSON metadata with full sponsoring information +6. Publishes kind 1 event with sponsoring confirmation message (includes text if provided) + +### 3. Integration Points + +#### Purchase Payments + +**File**: `lib/paymentPollingMain.ts` + +After a purchase payment is confirmed (zap receipt verified), the system: + +1. Sends private content to the user +2. Tracks content delivery +3. Triggers automatic transfer +4. **Publishes explicit payment note**: + - Retrieves article information to get category and seriesId + - Gets zap receipt to extract payment hash + - Calls `publishPurchaseNote` with all relevant information + +**Error Handling**: If note publication fails, the payment process continues (non-blocking). + +#### Review Tips + +**File**: `components/ReviewTipForm.tsx` + +Review tips are handled via zap requests. The explicit note publication should be triggered after zap receipt confirmation. Currently, the zap request is published, and the actual payment is handled by Alby/WebLN. + +**Note**: Review tip note publication should be integrated when zap receipt confirmation is implemented for review tips. + +#### Sponsoring Payments + +**File**: `lib/sponsoringPaymentTracking.ts` + +After a sponsoring payment transaction is verified on Bitcoin mainnet, the system: + +1. Verifies the transaction +2. Tracks the sponsoring payment +3. **Publishes explicit payment note** (if payer information is available) + +**Note**: Currently, sponsoring note publication requires payer information (pubkey, private key, category, text, etc.) which may not always be available at tracking time. This should be handled when the user submits the transaction ID. + +### 4. Zap Receipt Queries + +New file `lib/zapReceiptQueries.ts` provides: + +#### `getZapReceiptById` + +Retrieves a zap receipt event (kind 9735) by its ID. + +**Use Case**: Extract payment hash and other information from zap receipts for payment note publication. + +## Tag Structure + +### Purchase Payment Note Tags + +``` +#payment +#sciencefiction or #research +#id_ +#service_zapwall.fr +#version_0 +#kind_type_purchase +#amount_ +#payer_ +#recipient_ +#payment_hash_ +#zap_receipt_ (optional) +#article_ +#series_ (optional) +#json_ +``` + +### Review Tip Payment Note Tags + +``` +#payment +#sciencefiction or #research +#id_ +#service_zapwall.fr +#version_0 +#kind_type_review_tip +#amount_ +#payer_ +#recipient_ +#payment_hash_ +#zap_receipt_ (optional) +#article_ +#review_id_ +#series_ (optional) +#text_ (optional) +#json_ +``` + +### Sponsoring Payment Note Tags + +``` +#payment +#sciencefiction or #research +#id_ +#service_zapwall.fr +#version_0 +#kind_type_sponsoring +#amount_ +#payer_ +#recipient_ +#payment_hash_ +#series_ (optional) +#article_ (optional) +#text_ (optional) +#transaction_id_ (optional, for Bitcoin mainnet) +#json_ +``` + +## JSON Metadata Structure + +All payment notes include a `json` tag with complete payment information: + +### Purchase + +```json +{ + "type": "purchase", + "id": "_0_0", + "hash": "", + "version": 0, + "index": 0, + "payerPubkey": "", + "articleId": "", + "authorPubkey": "", + "amount": 800, + "paymentHash": "" +} +``` + +### Review Tip + +```json +{ + "type": "review_tip", + "id": "_0_0", + "hash": "", + "version": 0, + "index": 0, + "payerPubkey": "", + "articleId": "", + "reviewId": "", + "reviewerPubkey": "", + "authorPubkey": "", + "amount": 100, + "paymentHash": "", + "text": "" +} +``` + +### Sponsoring + +```json +{ + "type": "sponsoring", + "id": "_0_0", + "hash": "", + "version": 0, + "index": 0, + "payerPubkey": "", + "authorPubkey": "", + "amount": 4600000, + "paymentHash": "", + "seriesId": "", + "articleId": "", + "text": "", + "transactionId": "" +} +``` + +## Error Handling + +- Payment note publication failures do not block the payment process +- Errors are logged but do not prevent payment confirmation +- Users can still access content even if note publication fails + +## Future Improvements + +1. **Review Tip Note Publication**: Integrate automatic note publication after review tip zap receipt confirmation +2. **Sponsoring Note Publication**: Improve integration to capture payer information at transaction submission time +3. **Payment History**: Create UI to display user's payment history from payment notes +4. **Aggregation**: Use payment notes for financial aggregations and statistics +5. **Search**: Enable searching payment notes by various criteria (article, author, date, etc.) + +## Files Modified + +- `lib/nostrTagSystemTypes.ts`: Added `PaymentTags` interface +- `lib/nostrTagSystemBuild.ts`: Added `buildPaymentTags` function +- `lib/paymentNotes.ts`: New file with payment note publication functions +- `lib/paymentPollingMain.ts`: Integrated purchase note publication +- `lib/zapReceiptQueries.ts`: New file for zap receipt queries +- `lib/sponsoringPaymentTracking.ts`: Prepared for sponsoring note publication (currently commented out) + +## Related Documentation + +- `docs/object-identification-system.md`: Object ID format and structure +- `docs/tag-system.md`: Project tag system documentation +- `docs/payment-flows.md`: Payment flow documentation diff --git a/docs/session-summary-2026-01-05.md b/docs/session-summary-2026-01-05.md new file mode 100644 index 0000000..6e8ae9d --- /dev/null +++ b/docs/session-summary-2026-01-05.md @@ -0,0 +1,296 @@ +# Session Summary - 2026-01-05 + +**Author**: Équipe 4NK +**Date**: 2026-01-05 + +## Overview + +This document summarizes all modifications and implementations completed during this development session, focusing on object identification, caching, payment systems, A5 pages, and payment notes. + +## Major Features Implemented + +### 1. Object Identification System + +**Objective**: Implement a comprehensive object identification system with `id`, `hash`, `version`, and `index` fields for all objects. + +**Implementation**: +- ID format: `__` +- All objects now have: `id`, `hash`, `version`, `index` +- Hash generation using SHA-256 from canonical object representation +- Index management for duplicate hash handling +- Version management for object updates + +**Files Modified**: +- `types/nostr.ts`: Added fields to all object interfaces +- `lib/urlGenerator.ts`: Added `buildObjectId` and `parseObjectId` functions +- `lib/hashIdGenerator.ts`: Hash generation for all object types +- `lib/nostrEventParsing.ts`: Updated to extract and construct new ID fields +- `lib/objectCache.ts`: Updated IndexedDB cache to support new ID structure + +**Routes**: All object routes now use the new ID format: `https://zapwall.fr//` + +### 2. IndexedDB Caching System + +**Objective**: Implement per-object-type caching in IndexedDB with settings storage and last sync date tracking. + +**Implementation**: +- Separate IndexedDB stores for each object type (author, series, publication, review, purchase, sponsoring, review_tip) +- Settings store (excluding keys) for platform configuration +- Last synchronized day tracking for background sync resumption +- Database migration system (DB_VERSION incremented to 2) +- New indexes: `hash`, `index` for efficient lookups + +**Files Modified**: +- `lib/objectCache.ts`: Complete rewrite with new structure +- `components/CacheUpdateManager.tsx`: User-facing cache update button + +**Features**: +- Cache per object type +- Settings cache (excluding sensitive keys) +- Last sync date tracking +- Cache clearing and re-synchronization + +### 3. Payment Objects Extension + +**Objective**: Extend object/route/cache system to include article payments, sponsoring, and review acknowledgements. + +**Implementation**: +- New object types: `Purchase`, `Sponsoring`, `ReviewTip` +- Routes: `/purchase/[id]`, `/sponsoring/[id]`, `/review-tip/[id]` +- Query functions: `purchaseQueries.ts`, `sponsoringQueries.ts`, `reviewTipQueries.ts` +- Cache support for all new object types +- Parsing from zap receipts (kind 9735) + +**Files Created**: +- `lib/purchaseQueries.ts` +- `lib/sponsoringQueries.ts` +- `lib/reviewTipQueries.ts` +- `pages/purchase/[id].tsx` +- `pages/sponsoring/[id].tsx` +- `pages/review-tip/[id].tsx` + +**Files Modified**: +- `types/nostr.ts`: Added new interfaces +- `lib/objectCache.ts`: Added cache support +- `lib/nostrEventParsing.ts`: Added parsing functions +- `lib/userContentSync.ts`: Added sync functions + +### 4. A5 Page System for Publications + +**Objective**: Implement A5-sized pages within series publications, supporting both Markdown and image content. + +**Implementation**: +- New `Page` interface: `number`, `type: 'markdown' | 'image'`, `content` +- Pages stored in article `pages` array +- Two-column Markdown editor with live preview +- Page management: add, remove, edit pages +- Image upload similar to profile photos +- Serialization in Nostr events (JSON tag) +- Display component for published articles + +**Files Created**: +- `components/MarkdownEditorTwoColumns.tsx`: Two-column editor with page management +- `components/ArticlePages.tsx`: Display component for A5 pages + +**Files Modified**: +- `types/nostr.ts`: Added `Page` interface and `pages` to `Article` +- `lib/articlePublisherTypes.ts`: Added `pages` to `ArticleDraft` +- `lib/articleInvoice.ts`: Updated to include pages in JSON metadata +- `lib/metadataExtractor.ts`: Updated to extract pages from events +- `components/ArticleEditorForm.tsx`: Integrated two-column editor +- `components/ArticlePreview.tsx`: Integrated page display + +### 5. Optional Text Fields + +**Objective**: Add optional plain text messages to reviews, review tips, and sponsoring. + +**Implementation**: +- Added `text?: string` to `Review`, `ReviewTip`, `Sponsoring` interfaces +- Parsing from Nostr event tags +- Display in UI components +- Included in zap request tags + +**Files Modified**: +- `types/nostr.ts`: Added `text` field +- `lib/articleMutations.ts`: Updated `buildReviewEvent` to include text +- `lib/nostrEventParsing.ts`: Updated parsing to extract text +- `lib/zapRequestBuilder.ts`: Updated to include text in zap requests + +### 6. Review, Review Tip, and Sponsoring Forms + +**Objective**: Create user-facing forms for creating reviews, sending review tips, and sponsoring authors. + +**Implementation**: +- `ReviewForm`: Create reviews with optional title, required content, optional text +- `ReviewTipForm`: Send tips to reviewers with optional text message +- `SponsoringForm`: Sponsor authors with optional text message (Bitcoin mainnet) + +**Files Created**: +- `components/ReviewForm.tsx` +- `components/ReviewTipForm.tsx` +- `components/SponsoringForm.tsx` + +**Files Modified**: +- `components/ArticleReviews.tsx`: Integrated review and tip forms +- `pages/series/[id].tsx`: Integrated review display +- `pages/author/[pubkey].tsx`: Integrated sponsoring form +- `public/locales/fr.txt` and `public/locales/en.txt`: Added translations + +### 7. Full-Width Layout + +**Objective**: Allow the site to take up the full screen width. + +**Implementation**: +- Removed `max-w-*` constraints from all pages +- Updated layout classes across the application + +**Files Modified**: +- All page components (`pages/*.tsx`) +- `components/HomeView.tsx` + +### 8. Funding Gauge Priorities + +**Objective**: Set priorities for funding gauges: Priority 1 for AI, Priority 2 for Anchoring. + +**Implementation**: +- Updated `components/FundingGauge.tsx` to display two gauges with priorities +- Added translations for certification gauge + +**Files Modified**: +- `components/FundingGauge.tsx` +- `public/locales/fr.txt` and `public/locales/en.txt` + +### 9. Payment Notes System + +**Objective**: Create explicit payment notes (kind 1) for all confirmed payments with project tags. + +**Implementation**: +- Extended tag system with `'payment'` type +- Created `PaymentTags` interface +- Three publication functions: `publishPurchaseNote`, `publishReviewTipNote`, `publishSponsoringNote` +- Integration with payment confirmation flows +- Zap receipt query utilities + +**Files Created**: +- `lib/paymentNotes.ts`: Payment note publication functions +- `lib/zapReceiptQueries.ts`: Zap receipt query utilities + +**Files Modified**: +- `lib/nostrTagSystemTypes.ts`: Added `PaymentTags` +- `lib/nostrTagSystemBuild.ts`: Added `buildPaymentTags` +- `lib/paymentPollingMain.ts`: Integrated purchase note publication + +**Documentation**: See `docs/payment-notes-system.md` for detailed documentation. + +## Tag System Verification + +Verified that all note creation functions use the `buildTags` helper: +- `buildSeriesEvent`: ✅ Uses `buildTags` +- `buildReviewEvent`: ✅ Uses `buildTags` +- `buildAuthorPresentationEvent`: ✅ Uses `buildTags` +- `buildPreviewTags`: ✅ Uses `buildTags` +- Zap requests: ✅ Include `kind_type` and relevant tags + +## Technical Details + +### Object ID Format + +``` +id: __ +``` + +- `hash`: SHA-256 hash of canonical object representation +- `index`: Index for duplicate hashes (default: 0) +- `version`: Version number for updates (default: 0) + +### IndexedDB Schema + +- Stores: `author`, `series`, `publication`, `review`, `purchase`, `sponsoring`, `review_tip`, `settings` +- Indexes: `hash`, `index`, `version`, `hidden` +- Version: 2 (migrated from 1) + +### Payment Flow Integration + +1. **Purchase**: Zap receipt → Content delivery → Payment note publication +2. **Review Tip**: Zap request → Zap receipt (via Alby) → Payment note publication (to be integrated) +3. **Sponsoring**: Bitcoin transaction → Verification → Tracking → Payment note publication (to be integrated) + +## Internationalization + +Added translations for: +- A5 pages (`page.*`) +- Reviews (`review.*`) +- Review tips (`reviewTip.*`) +- Sponsoring (`sponsoring.*`) +- Funding gauge priorities +- Common optional field label + +## Testing Considerations + +- All new code compiles without TypeScript errors +- Linter checks pass +- No fallback mechanisms (as per project rules) +- Error handling with logging +- Non-blocking payment note publication + +## Known Limitations + +1. **Review Tip Notes**: Automatic publication after zap receipt confirmation not yet fully integrated +2. **Sponsoring Notes**: Requires payer information at transaction submission time (currently not captured) +3. **Payment History UI**: Not yet implemented (payment notes are published but not displayed in UI) + +## Next Steps + +1. Complete review tip note publication integration +2. Improve sponsoring note publication with payer information capture +3. Implement payment history UI +4. Add payment aggregation queries +5. Create payment search functionality + +## Files Summary + +### Created Files +- `lib/purchaseQueries.ts` +- `lib/sponsoringQueries.ts` +- `lib/reviewTipQueries.ts` +- `lib/paymentNotes.ts` +- `lib/zapReceiptQueries.ts` +- `lib/zapRequestBuilder.ts` +- `components/MarkdownEditorTwoColumns.tsx` +- `components/ArticlePages.tsx` +- `components/ReviewForm.tsx` +- `components/ReviewTipForm.tsx` +- `components/SponsoringForm.tsx` +- `pages/purchase/[id].tsx` +- `pages/sponsoring/[id].tsx` +- `pages/review-tip/[id].tsx` + +### Modified Files +- `types/nostr.ts` +- `lib/urlGenerator.ts` +- `lib/objectCache.ts` +- `lib/nostrEventParsing.ts` +- `lib/nostrTagSystemTypes.ts` +- `lib/nostrTagSystemBuild.ts` +- `lib/articlePublisherTypes.ts` +- `lib/articleInvoice.ts` +- `lib/metadataExtractor.ts` +- `lib/articleMutations.ts` +- `lib/paymentPollingMain.ts` +- `lib/userContentSync.ts` +- `components/ArticleEditorForm.tsx` +- `components/ArticlePreview.tsx` +- `components/ArticleReviews.tsx` +- `components/CacheUpdateManager.tsx` +- `components/FundingGauge.tsx` +- `pages/series/[id].tsx` +- `pages/author/[pubkey].tsx` +- All page layout files (removed max-w constraints) +- `public/locales/fr.txt` +- `public/locales/en.txt` + +## Related Documentation + +- `docs/payment-notes-system.md`: Detailed payment notes system documentation +- `docs/object-identification-system.md`: Object ID system (if exists) +- `docs/tag-system.md`: Tag system documentation (if exists) diff --git a/fixKnowledge/ssh-connection-errors-deployment.md b/fixKnowledge/ssh-connection-errors-deployment.md index 7300b6d..968d047 100644 --- a/fixKnowledge/ssh-connection-errors-deployment.md +++ b/fixKnowledge/ssh-connection-errors-deployment.md @@ -1,6 +1,6 @@ # SSH Connection Errors During Deployment -**Date**: 2024-12-19 +**Date**: 2024-12-19 **Auteur**: Équipe 4NK ## Problem Description @@ -176,4 +176,3 @@ None identified at this time. - SSH ControlMaster documentation - Deployment script: `deploy.sh` - Related documentation: `docs/deployment.md` - diff --git a/lib/purchaseQueries.ts b/lib/purchaseQueries.ts index 339fddf..ecf4506 100644 --- a/lib/purchaseQueries.ts +++ b/lib/purchaseQueries.ts @@ -7,7 +7,14 @@ import { getPrimaryRelaySync } from './config' import { MIN_EVENT_DATE } from './platformConfig' import { parseObjectId } from './urlGenerator' -function buildPurchaseFilters(articleId?: string, payerPubkey?: string, authorPubkey?: string) { +function buildPurchaseFilters(articleId?: string, payerPubkey?: string, authorPubkey?: string): Array<{ + kinds: number[] + since?: number + authors?: string[] + '#p'?: string[] + '#e'?: string[] + '#kind_type'?: string[] +}> { const filters: Array<{ kinds: number[] since?: number @@ -66,7 +73,7 @@ export async function getPurchaseById(purchaseId: string, timeoutMs: number = 50 const sub = createSubscription(pool, [relayUrl], filters) let finished = false - const done = async (value: Purchase | null) => { + const done = async (value: Purchase | null): Promise => { if (finished) { return } @@ -86,7 +93,9 @@ export async function getPurchaseById(purchaseId: string, timeoutMs: number = 50 } }) - sub.on('eose', () => done(null)) + sub.on('eose', (): void => { + void done(null) + }) setTimeout(() => done(null), timeoutMs).unref?.() }) } diff --git a/lib/reviewTipQueries.ts b/lib/reviewTipQueries.ts index 3b0b63e..89e15e2 100644 --- a/lib/reviewTipQueries.ts +++ b/lib/reviewTipQueries.ts @@ -71,7 +71,7 @@ export async function getReviewTipById(reviewTipId: string, timeoutMs: number = const sub = createSubscription(pool, [relayUrl], filters) let finished = false - const done = async (value: ReviewTip | null) => { + const done = async (value: ReviewTip | null): Promise => { if (finished) { return } @@ -91,7 +91,9 @@ export async function getReviewTipById(reviewTipId: string, timeoutMs: number = } }) - sub.on('eose', () => done(null)) + sub.on('eose', (): void => { + void done(null) + }) setTimeout(() => done(null), timeoutMs).unref?.() }) } diff --git a/lib/sponsoringQueries.ts b/lib/sponsoringQueries.ts index 8a46bba..8d1c47f 100644 --- a/lib/sponsoringQueries.ts +++ b/lib/sponsoringQueries.ts @@ -71,7 +71,7 @@ export async function getSponsoringById(sponsoringId: string, timeoutMs: number const sub = createSubscription(pool, [relayUrl], filters) let finished = false - const done = async (value: Sponsoring | null) => { + const done = async (value: Sponsoring | null): Promise => { if (finished) { return } @@ -91,7 +91,9 @@ export async function getSponsoringById(sponsoringId: string, timeoutMs: number } }) - sub.on('eose', () => done(null)) + sub.on('eose', (): void => { + void done(null) + }) setTimeout(() => done(null), timeoutMs).unref?.() }) }