nostr-websocket-utils 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +151 -103
  3. package/dist/__mocks__/extendedWsMock.d.ts +35 -0
  4. package/dist/__mocks__/extendedWsMock.js +156 -0
  5. package/dist/__mocks__/logger.d.ts +9 -0
  6. package/dist/__mocks__/logger.js +6 -0
  7. package/dist/__mocks__/mockLogger.d.ts +41 -0
  8. package/dist/__mocks__/mockLogger.js +47 -0
  9. package/dist/__mocks__/mockserver.d.ts +31 -0
  10. package/dist/__mocks__/mockserver.js +39 -0
  11. package/dist/__mocks__/wsMock.d.ts +26 -0
  12. package/dist/__mocks__/wsMock.js +120 -0
  13. package/dist/client.d.ts +105 -0
  14. package/dist/client.js +105 -0
  15. package/dist/core/client.d.ts +94 -0
  16. package/dist/core/client.js +360 -0
  17. package/dist/core/nostr-server.d.ts +27 -0
  18. package/dist/core/nostr-server.js +95 -0
  19. package/dist/core/queue.d.ts +61 -0
  20. package/dist/core/queue.js +108 -0
  21. package/dist/core/server.d.ts +27 -0
  22. package/dist/core/server.js +114 -0
  23. package/dist/crypto/bech32.d.ts +26 -0
  24. package/dist/crypto/bech32.js +163 -0
  25. package/dist/crypto/handlers.d.ts +11 -0
  26. package/dist/crypto/handlers.js +36 -0
  27. package/dist/crypto/index.d.ts +5 -0
  28. package/dist/crypto/index.js +5 -0
  29. package/dist/crypto/schnorr.d.ts +16 -0
  30. package/dist/crypto/schnorr.js +51 -0
  31. package/dist/endpoints/metrics.d.ts +29 -0
  32. package/dist/endpoints/metrics.js +101 -0
  33. package/dist/index.d.ts +11 -6
  34. package/dist/index.js +16 -4
  35. package/dist/nips/index.d.ts +19 -0
  36. package/dist/nips/index.js +34 -0
  37. package/dist/nips/nip-01.d.ts +34 -0
  38. package/dist/nips/nip-01.js +145 -0
  39. package/dist/nips/nip-02.d.ts +83 -0
  40. package/dist/nips/nip-02.js +123 -0
  41. package/dist/nips/nip-04.d.ts +36 -0
  42. package/dist/nips/nip-04.js +105 -0
  43. package/dist/nips/nip-05.d.ts +86 -0
  44. package/dist/nips/nip-05.js +151 -0
  45. package/dist/nips/nip-09.d.ts +92 -0
  46. package/dist/nips/nip-09.js +190 -0
  47. package/dist/nips/nip-11.d.ts +64 -0
  48. package/dist/nips/nip-11.js +154 -0
  49. package/dist/nips/nip-13.d.ts +73 -0
  50. package/dist/nips/nip-13.js +128 -0
  51. package/dist/nips/nip-15.d.ts +83 -0
  52. package/dist/nips/nip-15.js +101 -0
  53. package/dist/nips/nip-16.d.ts +88 -0
  54. package/dist/nips/nip-16.js +150 -0
  55. package/dist/nips/nip-19.d.ts +28 -0
  56. package/dist/nips/nip-19.js +103 -0
  57. package/dist/nips/nip-20.d.ts +59 -0
  58. package/dist/nips/nip-20.js +95 -0
  59. package/dist/nips/nip-22.d.ts +89 -0
  60. package/dist/nips/nip-22.js +142 -0
  61. package/dist/nips/nip-26.d.ts +52 -0
  62. package/dist/nips/nip-26.js +139 -0
  63. package/dist/nips/nip-28.d.ts +103 -0
  64. package/dist/nips/nip-28.js +170 -0
  65. package/dist/nips/nip-33.d.ts +94 -0
  66. package/dist/nips/nip-33.js +133 -0
  67. package/dist/nostr-server.d.ts +23 -0
  68. package/dist/nostr-server.js +44 -0
  69. package/dist/server.d.ts +13 -3
  70. package/dist/server.js +60 -33
  71. package/dist/transport/base.d.ts +54 -0
  72. package/dist/transport/base.js +104 -0
  73. package/dist/transport/websocket.d.ts +22 -0
  74. package/dist/transport/websocket.js +122 -0
  75. package/dist/types/events.d.ts +63 -0
  76. package/dist/types/events.js +5 -0
  77. package/dist/types/filters.d.ts +19 -0
  78. package/dist/types/filters.js +5 -0
  79. package/dist/types/handlers.d.ts +80 -0
  80. package/dist/types/handlers.js +5 -0
  81. package/dist/types/index.d.ts +118 -39
  82. package/dist/types/index.js +21 -1
  83. package/dist/types/logger.d.ts +40 -0
  84. package/dist/types/logger.js +5 -0
  85. package/dist/types/messages.d.ts +135 -0
  86. package/dist/types/messages.js +40 -0
  87. package/dist/types/nostr.d.ts +120 -39
  88. package/dist/types/nostr.js +5 -10
  89. package/dist/types/options.d.ts +154 -0
  90. package/dist/types/options.js +5 -0
  91. package/dist/types/relays.d.ts +26 -0
  92. package/dist/types/relays.js +5 -0
  93. package/dist/types/scoring.d.ts +47 -0
  94. package/dist/types/scoring.js +29 -0
  95. package/dist/types/socket.d.ts +99 -0
  96. package/dist/types/socket.js +5 -0
  97. package/dist/types/transport.d.ts +97 -0
  98. package/dist/types/transport.js +5 -0
  99. package/dist/types/validation.d.ts +50 -0
  100. package/dist/types/validation.js +5 -0
  101. package/dist/types/websocket.d.ts +172 -0
  102. package/dist/types/websocket.js +5 -0
  103. package/dist/utils/http.d.ts +10 -0
  104. package/dist/utils/http.js +24 -0
  105. package/dist/utils/logger.d.ts +11 -2
  106. package/dist/utils/logger.js +18 -13
  107. package/dist/utils/metrics.d.ts +81 -0
  108. package/dist/utils/metrics.js +206 -0
  109. package/dist/utils/rate-limiter.d.ts +85 -0
  110. package/dist/utils/rate-limiter.js +175 -0
  111. package/package.json +18 -21
@@ -0,0 +1,26 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ declare class MockWebSocket {
4
+ static OPEN: number;
5
+ static CLOSED: number;
6
+ static CONNECTING: number;
7
+ static CLOSING: number;
8
+ url: string;
9
+ readyState: number;
10
+ onopen: ((event: Event) => void) | null;
11
+ onclose: ((event: CloseEvent) => void) | null;
12
+ onmessage: ((event: MessageEvent) => void) | null;
13
+ eventListeners: {
14
+ [type: string]: ((data: Buffer) => void)[];
15
+ };
16
+ constructor(url: string | URL, _protocols?: string | string[]);
17
+ send(_data: unknown): void;
18
+ close(): void;
19
+ simulateOpen(): void;
20
+ simulateMessage(data: unknown): void;
21
+ simulateClose(): void;
22
+ addEventListener(type: string, listener: (data: Buffer) => void): void;
23
+ dispatchEvent(event: Event | CloseEvent | MessageEvent): boolean;
24
+ }
25
+ declare const mockWebSocket: MockWebSocket;
26
+ export default mockWebSocket;
@@ -0,0 +1,120 @@
1
+ class MockWebSocket {
2
+ constructor(url, _protocols) {
3
+ this.onopen = null;
4
+ this.onclose = null;
5
+ this.onmessage = null;
6
+ this.eventListeners = {};
7
+ this.url = typeof url === 'string' ? url : url.toString();
8
+ this.readyState = MockWebSocket.CONNECTING;
9
+ }
10
+ send(_data) {
11
+ // Implementation not needed for these tests
12
+ }
13
+ close() {
14
+ this.readyState = MockWebSocket.CLOSING;
15
+ this.simulateClose();
16
+ }
17
+ simulateOpen() {
18
+ this.readyState = MockWebSocket.OPEN;
19
+ const event = new MockEvent('open');
20
+ if (this.onopen)
21
+ this.onopen(event);
22
+ }
23
+ simulateMessage(data) {
24
+ const messageData = Buffer.from(JSON.stringify(data));
25
+ const listeners = this.eventListeners['message'] || [];
26
+ listeners.forEach(listener => listener(messageData));
27
+ }
28
+ simulateClose() {
29
+ this.readyState = MockWebSocket.CLOSED;
30
+ const event = new MockCloseEvent('close');
31
+ if (this.onclose)
32
+ this.onclose(event);
33
+ }
34
+ addEventListener(type, listener) {
35
+ if (!this.eventListeners[type]) {
36
+ this.eventListeners[type] = [];
37
+ }
38
+ this.eventListeners[type].push(listener);
39
+ }
40
+ dispatchEvent(event) {
41
+ if (event.type === 'close' && this.onclose) {
42
+ this.onclose(event);
43
+ }
44
+ else if (event.type === 'open' && this.onopen) {
45
+ this.onopen(event);
46
+ }
47
+ else if (event.type === 'message' && this.onmessage) {
48
+ this.onmessage(event);
49
+ }
50
+ return true;
51
+ }
52
+ }
53
+ MockWebSocket.OPEN = 1;
54
+ MockWebSocket.CLOSED = 3;
55
+ MockWebSocket.CONNECTING = 0;
56
+ MockWebSocket.CLOSING = 2;
57
+ // Set up the global WebSocket with proper typing
58
+ global.WebSocket = MockWebSocket;
59
+ class MockEvent {
60
+ constructor(type) {
61
+ this.NONE = 0;
62
+ this.CAPTURING_PHASE = 1;
63
+ this.AT_TARGET = 2;
64
+ this.BUBBLING_PHASE = 3;
65
+ this.target = null;
66
+ this.currentTarget = null;
67
+ this.eventPhase = 0;
68
+ this.bubbles = false;
69
+ this.cancelable = false;
70
+ this.defaultPrevented = false;
71
+ this.composed = false;
72
+ this.timeStamp = Date.now();
73
+ this.srcElement = null;
74
+ this.returnValue = true;
75
+ this.cancelBubble = false;
76
+ this.isTrusted = true;
77
+ this.type = type;
78
+ }
79
+ preventDefault() { }
80
+ stopPropagation() { }
81
+ stopImmediatePropagation() { }
82
+ composedPath() { return []; }
83
+ initEvent(_type, _bubbles, _cancelable) { }
84
+ }
85
+ class MockCloseEvent extends MockEvent {
86
+ constructor(type) {
87
+ super(type);
88
+ this.code = 1000;
89
+ this.reason = '';
90
+ this.wasClean = true;
91
+ }
92
+ }
93
+ /*
94
+ class MockMessageEvent extends MockEvent implements MessageEvent {
95
+ readonly data: unknown;
96
+ readonly origin: string = '';
97
+ readonly lastEventId: string = '';
98
+ readonly source: Window | MessagePort | ServiceWorker | null = null;
99
+ readonly ports: ReadonlyArray<MessagePort> = [];
100
+
101
+ constructor(data: unknown) {
102
+ super('message');
103
+ this.data = data;
104
+ }
105
+
106
+ initMessageEvent(
107
+ _type: string,
108
+ _bubbles?: boolean,
109
+ _cancelable?: boolean,
110
+ _data: unknown = null,
111
+ _origin: string = '',
112
+ _lastEventId: string = '',
113
+ _source: Window | MessagePort | ServiceWorker | null = null,
114
+ _ports: MessagePort[] = []
115
+ ): void {}
116
+ }
117
+ */
118
+ // Export an instance of MockWebSocket
119
+ const mockWebSocket = new MockWebSocket('ws://test.com');
120
+ export default mockWebSocket;
package/dist/client.d.ts CHANGED
@@ -1,6 +1,27 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
3
  import type { NostrWSOptions, NostrWSMessage } from './types/index.js';
4
+ /**
5
+ * WebSocket client implementation for Nostr protocol communication
6
+ * Extends EventEmitter to provide event-based message handling
7
+ *
8
+ * @extends EventEmitter
9
+ * @example
10
+ * ```typescript
11
+ * const client = new NostrWSClient('wss://relay.example.com', {
12
+ * logger: console,
13
+ * heartbeatInterval: 30000,
14
+ * handlers: {
15
+ * message: async (msg) => console.log('Received:', msg),
16
+ * error: (err) => console.error('Error:', err),
17
+ * close: () => console.log('Connection closed')
18
+ * }
19
+ * });
20
+ *
21
+ * await client.connect();
22
+ * client.send({ type: 'EVENT', data: { ... } });
23
+ * ```
24
+ */
4
25
  export declare class NostrWSClient extends EventEmitter {
5
26
  private url;
6
27
  private ws;
@@ -10,15 +31,99 @@ export declare class NostrWSClient extends EventEmitter {
10
31
  private reconnectAttempts;
11
32
  private messageQueue;
12
33
  private clientId;
34
+ /**
35
+ * Creates a new NostrWSClient instance
36
+ *
37
+ * @param {string} url - The WebSocket server URL to connect to
38
+ * @param {Partial<NostrWSOptions>} options - Configuration options
39
+ * @param {number} [options.heartbeatInterval=30000] - Interval for sending heartbeat messages in milliseconds
40
+ * @param {object} options.logger - Logger instance (required)
41
+ * @param {Function} [options.WebSocketImpl=WebSocket] - WebSocket implementation to use
42
+ * @param {object} [options.handlers] - Event handlers
43
+ * @param {Function} [options.handlers.message] - Message handler function
44
+ * @param {Function} [options.handlers.error] - Error handler function
45
+ * @param {Function} [options.handlers.close] - Connection close handler function
46
+ * @throws {Error} If logger is not provided
47
+ */
13
48
  constructor(url: string, options?: Partial<NostrWSOptions>);
49
+ /**
50
+ * Establishes a connection to the WebSocket server
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * client.connect();
55
+ * ```
56
+ */
14
57
  connect(): void;
58
+ /**
59
+ * Sets up event handlers for the WebSocket connection
60
+ *
61
+ * @private
62
+ */
15
63
  private setupEventHandlers;
64
+ /**
65
+ * Starts sending heartbeat messages at the specified interval
66
+ *
67
+ * @private
68
+ */
16
69
  private startHeartbeat;
70
+ /**
71
+ * Stops sending heartbeat messages
72
+ *
73
+ * @private
74
+ */
17
75
  private stopHeartbeat;
76
+ /**
77
+ * Handles reconnecting to the WebSocket server after a disconnection
78
+ *
79
+ * @private
80
+ */
18
81
  private handleReconnect;
82
+ /**
83
+ * Subscribes to a channel with optional filter
84
+ *
85
+ * @param {string} channel - Channel name
86
+ * @param {unknown} [filter] - Filter data
87
+ * @example
88
+ * ```typescript
89
+ * client.subscribe('channel-name', { ...filterData });
90
+ * ```
91
+ */
19
92
  subscribe(channel: string, filter?: unknown): void;
93
+ /**
94
+ * Unsubscribes from a channel
95
+ *
96
+ * @param {string} channel - Channel name
97
+ * @example
98
+ * ```typescript
99
+ * client.unsubscribe('channel-name');
100
+ * ```
101
+ */
20
102
  unsubscribe(channel: string): void;
103
+ /**
104
+ * Flushes the message queue by sending pending messages
105
+ *
106
+ * @private
107
+ */
21
108
  private flushMessageQueue;
109
+ /**
110
+ * Sends a message to the WebSocket server
111
+ *
112
+ * @param {NostrWSMessage} message - Message to send
113
+ * @returns {Promise<void>}
114
+ * @example
115
+ * ```typescript
116
+ * client.send({ type: 'EVENT', data: { ... } });
117
+ * ```
118
+ */
22
119
  send(message: NostrWSMessage): Promise<void>;
120
+ /**
121
+ * Closes the WebSocket connection
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * client.close();
126
+ * ```
127
+ */
23
128
  close(): void;
24
129
  }
package/dist/client.js CHANGED
@@ -1,7 +1,42 @@
1
1
  import { v4 as uuidv4 } from 'uuid';
2
2
  import WebSocket from 'ws';
3
3
  import { EventEmitter } from 'events';
4
+ /**
5
+ * WebSocket client implementation for Nostr protocol communication
6
+ * Extends EventEmitter to provide event-based message handling
7
+ *
8
+ * @extends EventEmitter
9
+ * @example
10
+ * ```typescript
11
+ * const client = new NostrWSClient('wss://relay.example.com', {
12
+ * logger: console,
13
+ * heartbeatInterval: 30000,
14
+ * handlers: {
15
+ * message: async (msg) => console.log('Received:', msg),
16
+ * error: (err) => console.error('Error:', err),
17
+ * close: () => console.log('Connection closed')
18
+ * }
19
+ * });
20
+ *
21
+ * await client.connect();
22
+ * client.send({ type: 'EVENT', data: { ... } });
23
+ * ```
24
+ */
4
25
  export class NostrWSClient extends EventEmitter {
26
+ /**
27
+ * Creates a new NostrWSClient instance
28
+ *
29
+ * @param {string} url - The WebSocket server URL to connect to
30
+ * @param {Partial<NostrWSOptions>} options - Configuration options
31
+ * @param {number} [options.heartbeatInterval=30000] - Interval for sending heartbeat messages in milliseconds
32
+ * @param {object} options.logger - Logger instance (required)
33
+ * @param {Function} [options.WebSocketImpl=WebSocket] - WebSocket implementation to use
34
+ * @param {object} [options.handlers] - Event handlers
35
+ * @param {Function} [options.handlers.message] - Message handler function
36
+ * @param {Function} [options.handlers.error] - Error handler function
37
+ * @param {Function} [options.handlers.close] - Connection close handler function
38
+ * @throws {Error} If logger is not provided
39
+ */
5
40
  constructor(url, options = {}) {
6
41
  super();
7
42
  this.url = url;
@@ -25,6 +60,14 @@ export class NostrWSClient extends EventEmitter {
25
60
  }
26
61
  };
27
62
  }
63
+ /**
64
+ * Establishes a connection to the WebSocket server
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * client.connect();
69
+ * ```
70
+ */
28
71
  connect() {
29
72
  if (this.ws) {
30
73
  this.options.logger.info('WebSocket connection already exists');
@@ -41,6 +84,11 @@ export class NostrWSClient extends EventEmitter {
41
84
  this.handleReconnect();
42
85
  }
43
86
  }
87
+ /**
88
+ * Sets up event handlers for the WebSocket connection
89
+ *
90
+ * @private
91
+ */
44
92
  setupEventHandlers() {
45
93
  if (!this.ws)
46
94
  return;
@@ -81,6 +129,11 @@ export class NostrWSClient extends EventEmitter {
81
129
  }
82
130
  });
83
131
  }
132
+ /**
133
+ * Starts sending heartbeat messages at the specified interval
134
+ *
135
+ * @private
136
+ */
84
137
  startHeartbeat() {
85
138
  if (this.heartbeatInterval)
86
139
  return;
@@ -90,12 +143,22 @@ export class NostrWSClient extends EventEmitter {
90
143
  }
91
144
  }, this.options.heartbeatInterval || 30000);
92
145
  }
146
+ /**
147
+ * Stops sending heartbeat messages
148
+ *
149
+ * @private
150
+ */
93
151
  stopHeartbeat() {
94
152
  if (this.heartbeatInterval) {
95
153
  clearInterval(this.heartbeatInterval);
96
154
  this.heartbeatInterval = null;
97
155
  }
98
156
  }
157
+ /**
158
+ * Handles reconnecting to the WebSocket server after a disconnection
159
+ *
160
+ * @private
161
+ */
99
162
  handleReconnect() {
100
163
  if (this.reconnectTimeout)
101
164
  return;
@@ -106,18 +169,42 @@ export class NostrWSClient extends EventEmitter {
106
169
  this.emit('reconnect');
107
170
  }, 5000);
108
171
  }
172
+ /**
173
+ * Subscribes to a channel with optional filter
174
+ *
175
+ * @param {string} channel - Channel name
176
+ * @param {unknown} [filter] - Filter data
177
+ * @example
178
+ * ```typescript
179
+ * client.subscribe('channel-name', { ...filterData });
180
+ * ```
181
+ */
109
182
  subscribe(channel, filter) {
110
183
  this.send({
111
184
  type: 'subscribe',
112
185
  data: { channel, filter }
113
186
  });
114
187
  }
188
+ /**
189
+ * Unsubscribes from a channel
190
+ *
191
+ * @param {string} channel - Channel name
192
+ * @example
193
+ * ```typescript
194
+ * client.unsubscribe('channel-name');
195
+ * ```
196
+ */
115
197
  unsubscribe(channel) {
116
198
  this.send({
117
199
  type: 'unsubscribe',
118
200
  data: { channel }
119
201
  });
120
202
  }
203
+ /**
204
+ * Flushes the message queue by sending pending messages
205
+ *
206
+ * @private
207
+ */
121
208
  flushMessageQueue() {
122
209
  while (this.messageQueue.length > 0 && this.ws?.readyState === WebSocket.OPEN) {
123
210
  const message = this.messageQueue.shift();
@@ -126,6 +213,16 @@ export class NostrWSClient extends EventEmitter {
126
213
  }
127
214
  }
128
215
  }
216
+ /**
217
+ * Sends a message to the WebSocket server
218
+ *
219
+ * @param {NostrWSMessage} message - Message to send
220
+ * @returns {Promise<void>}
221
+ * @example
222
+ * ```typescript
223
+ * client.send({ type: 'EVENT', data: { ... } });
224
+ * ```
225
+ */
129
226
  async send(message) {
130
227
  message.id = message.id || uuidv4();
131
228
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
@@ -140,6 +237,14 @@ export class NostrWSClient extends EventEmitter {
140
237
  this.handleReconnect();
141
238
  }
142
239
  }
240
+ /**
241
+ * Closes the WebSocket connection
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * client.close();
246
+ * ```
247
+ */
143
248
  close() {
144
249
  this.stopHeartbeat();
145
250
  if (this.reconnectTimeout) {
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @file WebSocket client implementation
3
+ * @module core/client
4
+ */
5
+ /// <reference types="node" />
6
+ import { EventEmitter } from 'events';
7
+ import { NostrWSMessage, NostrWSOptions, ConnectionState } from '../types';
8
+ /**
9
+ * WebSocket client implementation for Nostr protocol communication
10
+ * Extends EventEmitter to provide event-based message handling
11
+ */
12
+ export declare class NostrWSClient extends EventEmitter {
13
+ private readonly url;
14
+ private ws;
15
+ private state;
16
+ private messageQueue;
17
+ private reconnectTimeout;
18
+ private heartbeatInterval;
19
+ private heartbeatTimeout;
20
+ private missedHeartbeats;
21
+ private reconnectAttempts;
22
+ private subscriptions;
23
+ private readonly clientId;
24
+ private readonly options;
25
+ constructor(url: string, options?: Partial<NostrWSOptions>);
26
+ /**
27
+ * Gets the current connection state
28
+ */
29
+ get connectionState(): ConnectionState;
30
+ /**
31
+ * Updates the connection state and notifies handlers
32
+ */
33
+ private setState;
34
+ /**
35
+ * Establishes a connection to the WebSocket server
36
+ */
37
+ connect(): Promise<void>;
38
+ /**
39
+ * Sets up event handlers for the WebSocket connection
40
+ */
41
+ private setupEventHandlers;
42
+ /**
43
+ * Starts the heartbeat mechanism
44
+ */
45
+ private startHeartbeat;
46
+ /**
47
+ * Handles heartbeat responses
48
+ */
49
+ private handleHeartbeatResponse;
50
+ /**
51
+ * Stops the heartbeat mechanism
52
+ */
53
+ private stopHeartbeat;
54
+ /**
55
+ * Handles connection errors
56
+ */
57
+ private handleConnectionError;
58
+ /**
59
+ * Handles disconnection and cleanup
60
+ */
61
+ private handleDisconnection;
62
+ /**
63
+ * Initiates reconnection with exponential backoff
64
+ */
65
+ private reconnect;
66
+ /**
67
+ * Subscribes to a channel with optional filter
68
+ */
69
+ subscribe(channel: string, filter?: unknown): void;
70
+ /**
71
+ * Resubscribes to all active subscriptions
72
+ */
73
+ private resubscribeAll;
74
+ /**
75
+ * Unsubscribes from a channel
76
+ */
77
+ unsubscribe(channel: string): void;
78
+ /**
79
+ * Flushes the message queue by sending pending messages
80
+ */
81
+ private flushMessageQueue;
82
+ /**
83
+ * Sends a message immediately without queueing
84
+ */
85
+ private sendImmediate;
86
+ /**
87
+ * Sends a message to the WebSocket server
88
+ */
89
+ send(message: NostrWSMessage): Promise<void>;
90
+ /**
91
+ * Closes the WebSocket connection
92
+ */
93
+ close(): void;
94
+ }