@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 +1 -1
- package/src/index.ts +6 -1
- package/src/modules/Nip46.ts +115 -12
- package/src/modules/ProcessManager.ts +37 -8
package/package.json
CHANGED
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(
|
|
330
|
+
console.log('cancelNeedAuth');
|
|
326
331
|
this.fulfillCustomLaunchPromise();
|
|
327
332
|
this.authNostrService.cancelNostrConnect();
|
|
328
333
|
};
|
package/src/modules/Nip46.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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,
|
|
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
|
-
},
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
14
|
+
console.log('ProcessManager.onAuthUrl called, resetting timer');
|
|
15
|
+
this.resetTimer();
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
public onIframeUrl() {
|
|
19
|
-
|
|
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
|
-
|
|
38
|
+
console.log('ProcessManager.wait called, callTimer exists:', !!this.callTimer, 'callCount:', this.callCount);
|
|
26
39
|
|
|
27
40
|
if (!this.callTimer) {
|
|
28
|
-
this.callTimer = setTimeout(() =>
|
|
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;
|