From 43356f5dfb2f340cb8a7071e82a76388e411849d Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 23 May 2026 14:38:38 +0200 Subject: [PATCH] chore(deps): bump nostr-tools to ^2.23.3 to match lnbits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only breaking surface in webapp code is SimplePool.subscribeMany — 2.23 dropped the Filter[] form: a single subscription now takes one Filter, and multi-filter REQs go through subscribeMap. RelayHub gets an internal poolSubscribe() adapter that routes single-filter to pool.subscribe() and multi-filter to pool.subscribeMap(), preserving the external RelayHub.subscribe() API so no downstream modules change. Peer-dep bump (@noble/* and @scure/* → 2.x) is contained: nostr-tools is the only consumer in the lockfile, so the major version shift doesn't conflict with anything else. Co-Authored-By: Claude Opus 4.7 (1M context) --- package.json | 2 +- pnpm-lock.yaml | 88 ++++++++++++++--------------- src/modules/base/nostr/relay-hub.ts | 23 +++++++- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/package.json b/package.json index 106d1c5..1770e19 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "light-bolt11-decoder": "^3.2.0", "lucide-vue-next": "^0.474.0", "ngeohash": "^0.6.3", - "nostr-tools": "2.15.0", + "nostr-tools": "^2.23.3", "pinia": "^2.3.1", "qr-scanner": "^1.4.2", "qrcode": "^1.5.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8891845..d1a8b7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,8 +57,8 @@ importers: specifier: ^0.6.3 version: 0.6.3 nostr-tools: - specifier: 2.15.0 - version: 2.15.0(typescript@5.6.3) + specifier: ^2.23.3 + version: 2.23.5(typescript@5.6.3) pinia: specifier: ^2.3.1 version: 2.3.1(typescript@5.6.3)(vue@3.5.34(typescript@5.6.3)) @@ -1247,22 +1247,17 @@ packages: resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} engines: {node: '>= 12.13.0'} - '@noble/ciphers@0.5.3': - resolution: {integrity: sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==} + '@noble/ciphers@2.1.1': + resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==} + engines: {node: '>= 20.19.0'} - '@noble/curves@1.1.0': - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} + '@noble/curves@2.0.1': + resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} + engines: {node: '>= 20.19.0'} - '@noble/curves@1.2.0': - resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} - - '@noble/hashes@1.3.1': - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} - engines: {node: '>= 16'} - - '@noble/hashes@1.3.2': - resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} - engines: {node: '>= 16'} + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -1478,11 +1473,14 @@ packages: '@scure/base@1.1.1': resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} - '@scure/bip32@1.3.1': - resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==} + '@scure/base@2.0.0': + resolution: {integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==} - '@scure/bip39@1.2.1': - resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + '@scure/bip32@2.0.1': + resolution: {integrity: sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA==} + + '@scure/bip39@2.0.1': + resolution: {integrity: sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg==} '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} @@ -3535,8 +3533,8 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - nostr-tools@2.15.0: - resolution: {integrity: sha512-Jj/+UFbu3JbTAWP4ipPFNuyD4W5eVRBNAP+kmnoRCYp3bLmTrlQ0Qhs5O1xSQJTFpjdZqoS0zZOUKdxUdjc+pw==} + nostr-tools@2.23.5: + resolution: {integrity: sha512-Fa7ZlUdjfUW1P4E7H3yBexhOHYi18XNyvd2n7eNHkYR085xADX6Y8V8Vm7nT/XQajaFOBrptXmVIGkJ2E4vfVw==} peerDependencies: typescript: '>=5.0.0' peerDependenciesMeta: @@ -6204,19 +6202,13 @@ snapshots: dependencies: cross-spawn: 7.0.6 - '@noble/ciphers@0.5.3': {} + '@noble/ciphers@2.1.1': {} - '@noble/curves@1.1.0': + '@noble/curves@2.0.1': dependencies: - '@noble/hashes': 1.3.1 + '@noble/hashes': 2.0.1 - '@noble/curves@1.2.0': - dependencies: - '@noble/hashes': 1.3.2 - - '@noble/hashes@1.3.1': {} - - '@noble/hashes@1.3.2': {} + '@noble/hashes@2.0.1': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -6362,16 +6354,18 @@ snapshots: '@scure/base@1.1.1': {} - '@scure/bip32@1.3.1': - dependencies: - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.1 + '@scure/base@2.0.0': {} - '@scure/bip39@1.2.1': + '@scure/bip32@2.0.1': dependencies: - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.1 + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + '@scure/base': 2.0.0 + + '@scure/bip39@2.0.1': + dependencies: + '@noble/hashes': 2.0.1 + '@scure/base': 2.0.0 '@sindresorhus/is@4.6.0': {} @@ -8539,14 +8533,14 @@ snapshots: normalize-url@6.1.0: {} - nostr-tools@2.15.0(typescript@5.6.3): + nostr-tools@2.23.5(typescript@5.6.3): dependencies: - '@noble/ciphers': 0.5.3 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.1 - '@scure/bip32': 1.3.1 - '@scure/bip39': 1.2.1 + '@noble/ciphers': 2.1.1 + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + '@scure/base': 2.0.0 + '@scure/bip32': 2.0.1 + '@scure/bip39': 2.0.1 nostr-wasm: 0.1.0 optionalDependencies: typescript: 5.6.3 diff --git a/src/modules/base/nostr/relay-hub.ts b/src/modules/base/nostr/relay-hub.ts index 7cdd00f..add0037 100644 --- a/src/modules/base/nostr/relay-hub.ts +++ b/src/modules/base/nostr/relay-hub.ts @@ -1,4 +1,5 @@ import { SimplePool, type Filter, type Event, type Relay } from 'nostr-tools' +import type { SubscribeManyParams, SubCloser } from 'nostr-tools/abstract-pool' import { BaseService } from '@/core/base/BaseService' import { ref } from 'vue' @@ -438,7 +439,7 @@ export class RelayHub extends BaseService { } // Recreate the subscription - const subscription = this.pool.subscribeMany(availableRelays, config.filters, { + const subscription = this.poolSubscribe(availableRelays, config.filters, { onevent: (event: Event) => { config.onEvent?.(event) this.emit('event', { subscriptionId: id, event, relay: 'unknown' }) @@ -482,7 +483,7 @@ export class RelayHub extends BaseService { // Create subscription using the pool - const subscription = this.pool.subscribeMany(availableRelays, config.filters, { + const subscription = this.poolSubscribe(availableRelays, config.filters, { onevent: (event: Event) => { config.onEvent?.(event) this.emit('event', { subscriptionId: config.id, event, relay: 'unknown' }) @@ -550,6 +551,24 @@ export class RelayHub extends BaseService { return { success: successful, total } } + // nostr-tools 2.23+ deprecated the Filter[] form on pool.subscribeMany; route + // single-filter through pool.subscribe and multi-filter through subscribeMap + // so a single REQ-per-relay still carries every filter. + private poolSubscribe( + relays: string[], + filters: Filter[], + params: SubscribeManyParams + ): SubCloser { + if (filters.length === 0) { + throw new Error('Cannot subscribe with empty filters') + } + if (filters.length === 1) { + return this.pool.subscribe(relays, filters[0], params) + } + const requests = relays.flatMap(url => filters.map(filter => ({ url, filter }))) + return this.pool.subscribeMap(requests, params) + } + /** * Query events from relays (one-time fetch) */ -- 2.53.0