Fix nostr-tools API compatibility in nostr-client

- Remove useWebSocketImplementation (not needed in newer versions)
- Fix Relay.auth() callback signature to match nostr-tools API
- Fix filter type casting for subscribeMany and querySync
- Remove ws dependency (not needed for browser/node compatible builds)
- Mark connections as authenticated when no auth required

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-01-23 05:59:46 -05:00
commit 1b0c1c8c2b
2 changed files with 20 additions and 20 deletions

View file

@ -21,11 +21,9 @@
"validate-schemas": "tsx scripts/validate-schemas.ts" "validate-schemas": "tsx scripts/validate-schemas.ts"
}, },
"dependencies": { "dependencies": {
"nostr-tools": "^2.10.0", "nostr-tools": "^2.10.0"
"ws": "^8.18.0"
}, },
"devDependencies": { "devDependencies": {
"@types/ws": "^8.5.13",
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"typescript": "^5.7.0", "typescript": "^5.7.0",
"vitest": "^2.1.0", "vitest": "^2.1.0",

View file

@ -7,7 +7,7 @@
* - Automatic reconnection * - Automatic reconnection
*/ */
import { type Event, type Filter, Relay, SimplePool, useWebSocketImplementation } from 'nostr-tools' import { type Event, type Filter, Relay, SimplePool } from 'nostr-tools'
import { createAuthEvent } from './events.js' import { createAuthEvent } from './events.js'
import type { import type {
NostrClientConfig, NostrClientConfig,
@ -18,14 +18,6 @@ import type {
EventHandler, EventHandler,
} from './types.js' } from './types.js'
// Use ws for Node.js environments
if (typeof WebSocket === 'undefined') {
// Dynamic import for Node.js
import('ws').then((ws) => {
useWebSocketImplementation(ws.default as never)
})
}
interface RelayConnection { interface RelayConnection {
config: RelayConfig config: RelayConfig
relay: Relay | null relay: Relay | null
@ -102,6 +94,9 @@ export class NostrClient {
// Handle NIP-42 auth if required // Handle NIP-42 auth if required
if (connection.config.requiresAuth) { if (connection.config.requiresAuth) {
await this.handleAuth(connection) await this.handleAuth(connection)
} else {
// Mark as authenticated if no auth required
connection.state = 'authenticated'
} }
// Set up event handlers // Set up event handlers
@ -136,11 +131,8 @@ export class NostrClient {
connection.state = 'authenticating' connection.state = 'authenticating'
// Listen for AUTH challenge
// Note: nostr-tools handles this internally, but we need to provide the signed event
const relay = connection.relay const relay = connection.relay
// Subscribe to auth challenges
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
reject(new Error('Auth timeout')) reject(new Error('Auth timeout'))
@ -149,7 +141,11 @@ export class NostrClient {
// The relay will send an AUTH challenge when auth is required // The relay will send an AUTH challenge when auth is required
// We respond by publishing an auth event // We respond by publishing an auth event
relay relay
.auth(async (challenge: string) => { .auth(async (evt) => {
// evt is the challenge event template from the relay
// We need to extract the challenge and create our auth response
const challenge =
evt.tags?.find((t): t is [string, string] => t[0] === 'challenge')?.[1] ?? ''
const authEvent = createAuthEvent(this.config.identity, connection.config.url, challenge) const authEvent = createAuthEvent(this.config.identity, connection.config.url, challenge)
return authEvent return authEvent
}) })
@ -216,8 +212,11 @@ export class NostrClient {
throw new Error('No connected relays') throw new Error('No connected relays')
} }
const sub = this.pool.subscribeMany(connectedUrls, filters as Filter[], { // Cast filters to the expected type
onevent: (event) => { const typedFilters = filters as unknown as Filter[]
const sub = this.pool.subscribeMany(connectedUrls, typedFilters, {
onevent: (event: Event) => {
options.onEvent(event) options.onEvent(event)
this.emitEvent('event', { relay: 'pool', event }) this.emitEvent('event', { relay: 'pool', event })
}, },
@ -231,7 +230,7 @@ export class NostrClient {
this.subscriptions.set(id, { this.subscriptions.set(id, {
id, id,
filters: filters as Filter[], filters: typedFilters,
options, options,
close: () => sub.close(), close: () => sub.close(),
}) })
@ -262,7 +261,10 @@ export class NostrClient {
throw new Error('No connected relays') throw new Error('No connected relays')
} }
return this.pool.querySync(connectedUrls, filters as Filter[]) // Cast filters to the expected type
const typedFilters = filters as unknown as Filter[]
return this.pool.querySync(connectedUrls, typedFilters)
} }
/** /**