@konemono/nostr-login 1.7.24 → 1.7.26

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konemono/nostr-login",
3
- "version": "1.7.24",
3
+ "version": "1.7.26",
4
4
  "description": "",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
package/src/index.ts CHANGED
@@ -93,6 +93,11 @@ export class NostrLoginInitializer {
93
93
  this.bannerManager.onUserInfo(info);
94
94
  });
95
95
 
96
+ this.authNostrService.on('reconnecting', () => {
97
+ // リレー再接続中はProcessManagerのタイマーをリセット
98
+ this.processManager.onIframeUrl();
99
+ });
100
+
96
101
  this.modalManager.on('onAuthUrlClick', url => {
97
102
  this.openPopup(url);
98
103
  });
@@ -322,7 +327,7 @@ export class NostrLoginInitializer {
322
327
  };
323
328
 
324
329
  public cancelNeedAuth = () => {
325
- console.log("cancelNeedAuth");
330
+ console.log('cancelNeedAuth');
326
331
  this.fulfillCustomLaunchPromise();
327
332
  this.authNostrService.cancelNostrConnect();
328
333
  };
@@ -2,8 +2,10 @@ import NDK, { NDKEvent, NDKFilter, NDKNip46Signer, NDKNostrRpc, NDKRpcRequest, N
2
2
  import { validateEvent, verifySignature } from 'nostr-tools';
3
3
  import { PrivateKeySigner } from './Signer';
4
4
  import { NIP46_TIMEOUT } from '../const';
5
+ import ProcessManager from './ProcessManager';
5
6
 
6
7
  class NostrRpc extends NDKNostrRpc {
8
+ protected processManager?: ProcessManager;
7
9
  protected _ndk: NDK;
8
10
  protected _signer: PrivateKeySigner;
9
11
  protected requests: Set<string> = new Set();
@@ -11,10 +13,11 @@ class NostrRpc extends NDKNostrRpc {
11
13
  private sub?: NDKSubscription;
12
14
  protected _useNip44: boolean = false;
13
15
 
14
- public constructor(ndk: NDK, signer: PrivateKeySigner) {
16
+ public constructor(ndk: NDK, signer: PrivateKeySigner, processManager?: ProcessManager) {
15
17
  super(ndk, signer, ndk.debug.extend('nip46:signer:rpc'));
16
18
  this._ndk = ndk;
17
19
  this._signer = signer;
20
+ this.processManager = processManager;
18
21
  }
19
22
 
20
23
  public async subscribe(filter: NDKFilter): Promise<NDKSubscription> {
@@ -38,7 +41,7 @@ class NostrRpc extends NDKNostrRpc {
38
41
  this.requestTimeouts.clear();
39
42
  }
40
43
 
41
- private clearTimeout(id: string) {
44
+ protected clearTimeout(id: string) {
42
45
  const timeout = this.requestTimeouts.get(id);
43
46
  if (timeout) {
44
47
  clearTimeout(timeout);
@@ -145,43 +148,109 @@ class NostrRpc extends NDKNostrRpc {
145
148
  }
146
149
 
147
150
  protected async ensureConnected(): Promise<void> {
148
- const connectedRelays = Array.from(this._ndk.pool.relays.values()).filter(r => r.status === 1);
151
+ const relays = Array.from(this._ndk.pool.relays.values());
152
+ console.log(
153
+ 'Checking relay connections:',
154
+ relays.map(r => ({ url: r.url, status: r.status })),
155
+ );
156
+
157
+ const connectedRelays = relays.filter(r => r.status === 1);
149
158
 
150
159
  if (connectedRelays.length === 0) {
151
- console.log('No connected relays, reconnecting...');
160
+ console.log('No connected relays, forcing reconnection...');
161
+
162
+ // 既存の接続を全てクリーンアップ
163
+ for (const relay of relays) {
164
+ try {
165
+ await relay.disconnect();
166
+ } catch (e) {
167
+ console.log('Error disconnecting relay:', relay.url, e);
168
+ }
169
+ }
170
+
171
+ // 再接続
152
172
  await this._ndk.connect();
153
173
 
174
+ // 接続確立を待つ
154
175
  await new Promise<void>((resolve, reject) => {
155
176
  const timeout = setTimeout(() => {
177
+ const status = Array.from(this._ndk.pool.relays.values()).map(r => ({ url: r.url, status: r.status }));
178
+ console.error('Failed to reconnect to relays within 10s. Status:', status);
156
179
  reject(new Error('Failed to reconnect to relays'));
157
- }, 5000);
180
+ }, 10000);
158
181
 
159
182
  const checkConnection = () => {
160
183
  const connected = Array.from(this._ndk.pool.relays.values()).filter(r => r.status === 1);
161
184
  if (connected.length > 0) {
162
185
  clearTimeout(timeout);
163
- console.log('Reconnected to', connected.length, 'relays');
186
+ console.log(
187
+ 'Successfully reconnected to',
188
+ connected.length,
189
+ 'relays:',
190
+ connected.map(r => r.url),
191
+ );
164
192
  resolve();
165
193
  } else {
166
- setTimeout(checkConnection, 100);
194
+ setTimeout(checkConnection, 200);
167
195
  }
168
196
  };
169
197
  checkConnection();
170
198
  });
199
+ } else {
200
+ console.log(
201
+ 'Already connected to',
202
+ connectedRelays.length,
203
+ 'relays:',
204
+ connectedRelays.map(r => r.url),
205
+ );
171
206
  }
172
207
  }
173
208
 
174
209
  public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise<NDKRpcResponse> {
175
- await this.ensureConnected();
210
+ console.log('sendRequest called:', method, 'to', remotePubkey);
211
+
212
+ try {
213
+ this.processManager?.pause();
214
+ await this.ensureConnected();
215
+ } catch (e) {
216
+ console.error('Failed to ensure connection:', e);
217
+ if (cb) {
218
+ cb({
219
+ id: '',
220
+ result: '',
221
+ error: 'Failed to connect to relays: ' + (e as Error).message,
222
+ event: undefined as any,
223
+ });
224
+ }
225
+ throw e;
226
+ } finally {
227
+ this.processManager?.resume();
228
+ }
176
229
 
177
230
  const id = this.getId();
178
231
 
179
232
  this.setResponseHandler(id, cb);
180
233
 
181
234
  const event = await this.createRequestEvent(id, remotePubkey, method, params, kind);
182
- console.log('sendRequest', { event, method, remotePubkey, params });
235
+ console.log('sendRequest event created', { event, method, remotePubkey, params });
183
236
 
184
- await event.publish();
237
+ try {
238
+ await event.publish();
239
+ console.log('sendRequest event published successfully');
240
+ } catch (e) {
241
+ console.error('Failed to publish event:', e);
242
+ this.clearTimeout(id);
243
+ this.requests.delete(id);
244
+ if (cb) {
245
+ cb({
246
+ id,
247
+ result: '',
248
+ error: 'Failed to publish event: ' + (e as Error).message,
249
+ event: undefined as any,
250
+ });
251
+ }
252
+ throw e;
253
+ }
185
254
 
186
255
  // @ts-ignore
187
256
  return undefined as NDKRpcResponse;
@@ -313,8 +382,26 @@ export class IframeNostrRpc extends NostrRpc {
313
382
  }
314
383
 
315
384
  public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise<NDKRpcResponse> {
385
+ console.log('IframeNostrRpc.sendRequest called:', method, 'iframePort:', !!this.iframePort);
386
+
316
387
  if (!this.iframePort) {
317
- await this.ensureConnected();
388
+ try {
389
+ this.processManager?.pause();
390
+ await this.ensureConnected();
391
+ } catch (e) {
392
+ console.error('Failed to ensure connection:', e);
393
+ if (cb) {
394
+ cb({
395
+ id: '',
396
+ result: '',
397
+ error: 'Failed to connect to relays: ' + (e as Error).message,
398
+ event: undefined as any,
399
+ });
400
+ }
401
+ throw e;
402
+ } finally {
403
+ this.processManager?.resume();
404
+ }
318
405
  }
319
406
 
320
407
  const id = this.getId();
@@ -329,7 +416,23 @@ export class IframeNostrRpc extends NostrRpc {
329
416
  console.log('iframe-nip46 sending request to', this.peerOrigin, event.rawEvent());
330
417
  this.iframePort.postMessage(event.rawEvent());
331
418
  } else {
332
- await event.publish();
419
+ try {
420
+ await event.publish();
421
+ console.log('Request published to relays successfully');
422
+ } catch (e) {
423
+ console.error('Failed to publish event:', e);
424
+ this.clearTimeout(id);
425
+ this.requests.delete(id);
426
+ if (cb) {
427
+ cb({
428
+ id,
429
+ result: '',
430
+ error: 'Failed to publish event: ' + (e as Error).message,
431
+ event: undefined as any,
432
+ });
433
+ }
434
+ throw e;
435
+ }
333
436
  }
334
437
 
335
438
  // @ts-ignore
@@ -2,6 +2,7 @@ import { EventEmitter } from 'tseep';
2
2
  import { CALL_TIMEOUT } from '../const';
3
3
 
4
4
  class ProcessManager extends EventEmitter {
5
+ private paused = false;
5
6
  private callCount: number = 0;
6
7
  private callTimer: NodeJS.Timeout | undefined;
7
8
 
@@ -10,22 +11,38 @@ class ProcessManager extends EventEmitter {
10
11
  }
11
12
 
12
13
  public onAuthUrl() {
13
- if (Boolean(this.callTimer)) {
14
- clearTimeout(this.callTimer);
15
- }
14
+ console.log('ProcessManager.onAuthUrl called, resetting timer');
15
+ this.resetTimer();
16
16
  }
17
17
 
18
18
  public onIframeUrl() {
19
- if (Boolean(this.callTimer)) {
19
+ console.log('ProcessManager.onIframeUrl called, resetting timer');
20
+ this.resetTimer();
21
+ }
22
+
23
+ private resetTimer() {
24
+ if (this.callTimer) {
20
25
  clearTimeout(this.callTimer);
26
+ console.log('ProcessManager: timer reset');
27
+ }
28
+ if (this.callCount > 0) {
29
+ this.callTimer = setTimeout(() => {
30
+ console.log('ProcessManager: timeout reached, emitting onCallTimeout');
31
+ this.emit('onCallTimeout');
32
+ }, CALL_TIMEOUT);
33
+ console.log(`ProcessManager: new timer set for ${CALL_TIMEOUT} ms`);
21
34
  }
22
35
  }
23
36
 
24
37
  public async wait<T>(cb: () => Promise<T>): Promise<T> {
25
- // FIXME only allow 1 parallel req
38
+ console.log('ProcessManager.wait called, callTimer exists:', !!this.callTimer, 'callCount:', this.callCount);
26
39
 
27
40
  if (!this.callTimer) {
28
- this.callTimer = setTimeout(() => this.emit('onCallTimeout'), CALL_TIMEOUT);
41
+ this.callTimer = setTimeout(() => {
42
+ console.log('ProcessManager: timeout reached, emitting onCallTimeout');
43
+ this.emit('onCallTimeout');
44
+ }, CALL_TIMEOUT);
45
+ console.log(`Setting up timeout timer for ${CALL_TIMEOUT} ms`);
29
46
  }
30
47
 
31
48
  if (!this.callCount) {
@@ -57,11 +74,23 @@ class ProcessManager extends EventEmitter {
57
74
  throw error;
58
75
  }
59
76
 
60
- // we can't return undefined bcs an exception is
61
- // thrown above on error
62
77
  // @ts-ignore
63
78
  return result;
64
79
  }
80
+ public pause() {
81
+ if (this.callTimer) clearTimeout(this.callTimer);
82
+ this.callTimer = undefined;
83
+ this.paused = true;
84
+ }
85
+
86
+ public resume() {
87
+ this.paused = false;
88
+ if (this.callCount > 0 && !this.callTimer) {
89
+ this.callTimer = setTimeout(() => {
90
+ this.emit('onCallTimeout');
91
+ }, CALL_TIMEOUT);
92
+ }
93
+ }
65
94
  }
66
95
 
67
96
  export default ProcessManager;