@konemono/nostr-login 1.11.1 → 1.11.3

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.
@@ -1,104 +1,26 @@
1
- import NDK, { NDKEvent, NDKFilter, NDKNip46Signer, NDKNostrRpc, NDKRpcRequest, NDKRpcResponse, NDKSubscription, NDKSubscriptionCacheUsage, NostrEvent } from '@nostr-dev-kit/ndk';
2
- import { validateEvent } from 'nostr-tools';
1
+ import NDK, { NDKEvent, NDKFilter, NDKNip46Signer, NDKNostrRpc, NDKRpcRequest, NDKRpcResponse, NDKSubscription, NDKSubscriptionCacheUsage, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk';
2
+ import { validateEvent, verifySignature } from 'nostr-tools';
3
3
  import { PrivateKeySigner } from './Signer';
4
4
  import { NIP46_REQUEST_TIMEOUT, NIP46_CONNECT_TIMEOUT } from '../const';
5
+ import { EventEmitter } from 'events';
5
6
 
6
7
  // タイムアウト付きPromiseラッパー
7
8
  function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T> {
8
9
  return Promise.race([promise, new Promise<T>((_, reject) => setTimeout(() => reject(new Error(errorMessage)), timeoutMs))]);
9
10
  }
10
11
 
11
- /**
12
- * NDKのリレー接続を待機する
13
- */
14
- export function waitForConnection(ndk: NDK, timeout: number): Promise<void> {
15
- return new Promise((resolve, reject) => {
16
- const start = Date.now();
17
-
18
- const check = () => {
19
- // 接続済みリレーがあるか確認
20
- const connected = Array.from(ndk.pool.relays.values()).some(relay => relay.status === 1); // 1 = CONNECTED
21
-
22
- if (connected) {
23
- resolve();
24
- } else if (Date.now() - start > timeout) {
25
- reject(new Error(`接続タイムアウト: ${timeout}ms`));
26
- } else {
27
- setTimeout(check, 100);
28
- }
29
- };
30
-
31
- check();
32
- });
33
- }
34
-
35
- /**
36
- * NDKの接続を強制的に確立する
37
- */
38
- export async function ensureNDKConnection(ndk: NDK, timeout: number): Promise<void> {
39
- // connect()は冪等なので安全
40
- await ndk.connect();
41
- await waitForConnection(ndk, timeout);
42
- }
43
-
44
- /**
45
- * NIP-46専用リレーも含めて接続を確立する
46
- */
47
- export async function ensureNIP46Connection(ndk: NDK, timeout: number): Promise<void> {
48
- try {
49
- await ensureNDKConnection(ndk, timeout);
50
- } catch (e) {
51
- console.warn('Initial connection attempt failed, retrying with force disconnect...', e);
52
- // 接続数0なら明示的に全切断して再試行
53
- if (Array.from(ndk.pool.relays.values()).filter(r => r.status === 1).length === 0) {
54
- ndk.pool.relays.forEach(relay => {
55
- try {
56
- relay.disconnect();
57
- } catch (err) {
58
- console.error('Error disconnecting relay:', err);
59
- }
60
- });
61
- // タイムアウトを延長して再試行
62
- await ensureNDKConnection(ndk, timeout * 2);
63
- } else {
64
- throw e;
65
- }
66
- }
67
-
68
- // NIP-46用リレーが個別に定義されている場合の接続確認
69
- // @ts-ignore
70
- const signerRelays = ndk.signer?.relayUrls;
71
- if (signerRelays && Array.isArray(signerRelays)) {
72
- for (const url of signerRelays) {
73
- const relay = ndk.pool.getRelay(url);
74
- if (relay && relay.status !== 1) {
75
- await relay.connect();
76
- }
77
- }
78
- }
79
-
80
- // 最終チェック
81
- const connectedRelays = Array.from(ndk.pool.relays.values()).filter(r => r.status === 1);
82
- if (connectedRelays.length === 0) {
83
- throw new Error('リレー接続に失敗しました');
84
- }
85
- }
86
-
87
12
  class NostrRpc extends NDKNostrRpc {
88
13
  protected _ndk: NDK;
89
14
  protected _signer: PrivateKeySigner;
90
15
  protected requests: Set<string> = new Set();
91
16
  private sub?: NDKSubscription;
92
17
  protected _useNip44: boolean = false;
93
- private reconnectAttempts: number = 0;
94
- private maxReconnectAttempts: number = 3;
95
- private reconnectDelay: number = 2000;
18
+ private eventEmitter: EventEmitter = new EventEmitter();
96
19
 
97
20
  public constructor(ndk: NDK, signer: PrivateKeySigner) {
98
21
  super(ndk, signer, ndk.debug.extend('nip46:signer:rpc'));
99
22
  this._ndk = ndk;
100
23
  this._signer = signer;
101
- this.setupConnectionMonitoring();
102
24
  }
103
25
 
104
26
  public async subscribe(filter: NDKFilter): Promise<NDKSubscription> {
@@ -213,97 +135,22 @@ class NostrRpc extends NDKNostrRpc {
213
135
  return withTimeout(this.connect(pubkey, token, perms), timeoutMs, `Connection timeout after ${timeoutMs}ms`);
214
136
  }
215
137
 
216
- // タイムアウト対応のsendRequest
217
- public async sendRequestWithTimeout(
218
- remotePubkey: string,
219
- method: string,
220
- params: string[] = [],
221
- kind = 24133,
222
- timeoutMs: number = NIP46_REQUEST_TIMEOUT,
223
- ): Promise<NDKRpcResponse> {
224
- return withTimeout(
225
- new Promise<NDKRpcResponse>((resolve, reject) => {
226
- this.sendRequest(remotePubkey, method, params, kind, response => {
227
- if (response.error) {
228
- reject(new Error(response.error));
229
- } else {
230
- resolve(response);
231
- }
232
- });
233
- }),
234
- timeoutMs,
235
- `Request timeout after ${timeoutMs}ms for method: ${method}`,
236
- );
237
- }
238
-
239
- // 接続監視のセットアップ
240
- private setupConnectionMonitoring() {
241
- // アプリがフォアグラウンドに戻ったときの処理
242
- if (typeof document !== 'undefined') {
243
- document.addEventListener('visibilitychange', async () => {
244
- if (document.visibilityState === 'visible') {
245
- console.log('App visible, checking relay connections...');
246
- await this.ensureConnected();
138
+ // ping実装
139
+ public async ping(remotePubkey: string): Promise<void> {
140
+ return new Promise<void>((ok, err) => {
141
+ this.sendRequest(remotePubkey, 'ping', [], 24133, (response: NDKRpcResponse) => {
142
+ if (response.result === 'pong') {
143
+ ok();
144
+ } else {
145
+ err(new Error(response.error || 'ping failed'));
247
146
  }
248
147
  });
249
- }
250
-
251
- // オンライン/オフライン検知
252
- if (typeof window !== 'undefined') {
253
- window.addEventListener('online', async () => {
254
- console.log('Network online, reconnecting relays...');
255
- await this.reconnect();
256
- });
257
- }
258
- }
259
-
260
- // 接続を確認して必要なら再接続
261
- private async ensureConnected(): Promise<void> {
262
- const connectedRelays = Array.from(this._ndk.pool.relays.values()).filter(r => r.status === 1); // 1 = CONNECTED
263
-
264
- if (connectedRelays.length === 0) {
265
- console.log('No connected relays, attempting reconnection...');
266
- await this.reconnect();
267
- }
148
+ });
268
149
  }
269
150
 
270
- // 再接続処理
271
- protected async reconnect(): Promise<void> {
272
- if (this.reconnectAttempts >= this.maxReconnectAttempts) {
273
- console.error('Max reconnection attempts reached');
274
- this.emit('reconnectFailed');
275
- return;
276
- }
277
-
278
- this.reconnectAttempts++;
279
- console.log(`Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
280
-
281
- try {
282
- // サブスクリプションを停止
283
- if (this.sub) {
284
- this.sub.stop();
285
- }
286
-
287
- // 少し待ってから再接続
288
- await new Promise(resolve => setTimeout(resolve, this.reconnectDelay));
289
-
290
- // 再接続
291
- await this._ndk.connect();
292
-
293
- // サブスクリプションを再開
294
- if (this.sub) {
295
- await this.sub.start();
296
- }
297
-
298
- this.reconnectAttempts = 0;
299
- this.emit('reconnected');
300
- console.log('Successfully reconnected to relays');
301
- } catch (e) {
302
- console.error('Reconnection failed:', e);
303
-
304
- // リトライ
305
- setTimeout(() => this.reconnect(), this.reconnectDelay * this.reconnectAttempts);
306
- }
151
+ // タイムアウト対応のping
152
+ public async pingWithTimeout(remotePubkey: string, timeoutMs: number = 10000): Promise<void> {
153
+ return withTimeout(this.ping(remotePubkey), timeoutMs, `Ping timeout after ${timeoutMs}ms`);
307
154
  }
308
155
 
309
156
  protected getId(): string {
@@ -311,9 +158,6 @@ class NostrRpc extends NDKNostrRpc {
311
158
  }
312
159
 
313
160
  public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise<NDKRpcResponse> {
314
- // リクエスト送信前に接続を確認
315
- await ensureNIP46Connection(this._ndk, 5000);
316
-
317
161
  const id = this.getId();
318
162
 
319
163
  // response handler will deduplicate auth urls and responses
@@ -341,10 +185,10 @@ class NostrRpc extends NDKNostrRpc {
341
185
  return new Promise<NDKRpcResponse>(() => {
342
186
  const responseHandler = (response: NDKRpcResponse) => {
343
187
  if (response.result === 'auth_url') {
344
- this.once(`response-${id}`, responseHandler);
188
+ this.eventEmitter.once(`response-${id}`, responseHandler);
345
189
  if (!authUrlSent) {
346
190
  authUrlSent = true;
347
- this.emit('authUrl', response.error);
191
+ this.eventEmitter.emit('authUrl', response.error);
348
192
  }
349
193
  } else if (cb) {
350
194
  if (this.requests.has(id)) {
@@ -355,7 +199,7 @@ class NostrRpc extends NDKNostrRpc {
355
199
  }
356
200
  };
357
201
 
358
- this.once(`response-${id}`, responseHandler);
202
+ this.eventEmitter.once(`response-${id}`, responseHandler);
359
203
  });
360
204
  }
361
205
 
@@ -379,15 +223,28 @@ class NostrRpc extends NDKNostrRpc {
379
223
 
380
224
  return event;
381
225
  }
226
+
227
+ // EventEmitter互換メソッド
228
+ public override on = <EventKey extends string | symbol = string>(
229
+ event: EventKey,
230
+ listener: (...args: any[]) => void
231
+ ): this => {
232
+ this.eventEmitter.on(event as string, listener);
233
+ return this;
234
+ }
235
+
236
+ public override emit = <EventKey extends string | symbol = string>(
237
+ event: EventKey,
238
+ ...args: any[]
239
+ ): boolean => {
240
+ return this.eventEmitter.emit(event as string, ...args);
241
+ }
382
242
  }
383
243
 
384
244
  export class IframeNostrRpc extends NostrRpc {
385
245
  private peerOrigin?: string;
386
246
  private iframePort?: MessagePort;
387
247
  private iframeRequests = new Map<string, { id: string; pubkey: string }>();
388
- private heartbeatInterval?: number;
389
- private lastResponseTime: number = Date.now();
390
- private heartbeatTimeoutMs: number = 30000; // 30秒応答がなければ再接続
391
248
 
392
249
  public constructor(ndk: NDK, localSigner: PrivateKeySigner, iframePeerOrigin?: string) {
393
250
  super(ndk, localSigner);
@@ -408,32 +265,10 @@ export class IframeNostrRpc extends NostrRpc {
408
265
  );
409
266
  }
410
267
 
411
- // ハートビート開始
412
- private startHeartbeat() {
413
- this.stopHeartbeat();
414
-
415
- this.heartbeatInterval = window.setInterval(async () => {
416
- const timeSinceLastResponse = Date.now() - this.lastResponseTime;
417
-
418
- if (timeSinceLastResponse > this.heartbeatTimeoutMs) {
419
- console.warn('No response from relay for too long, reconnecting...');
420
- await this.reconnect();
421
- }
422
- }, 10000); // 10秒ごとにチェック
423
- }
424
-
425
- private stopHeartbeat() {
426
- if (this.heartbeatInterval) {
427
- clearInterval(this.heartbeatInterval);
428
- this.heartbeatInterval = undefined;
429
- }
430
- }
431
-
432
268
  public setWorkerIframePort(port: MessagePort) {
433
269
  if (!this.peerOrigin) throw new Error('Unexpected iframe port');
434
270
 
435
271
  this.iframePort = port;
436
- this.startHeartbeat();
437
272
 
438
273
  // to make sure Chrome doesn't terminate the channel
439
274
  setInterval(() => {
@@ -455,10 +290,9 @@ export class IframeNostrRpc extends NostrRpc {
455
290
  const event = ev.data;
456
291
 
457
292
  if (!validateEvent(event)) throw new Error('Invalid event from iframe');
293
+ if (!verifySignature(event)) throw new Error('Invalid event signature from iframe');
458
294
  const nevent = new NDKEvent(this._ndk, event);
459
295
  const parsedEvent = await this.parseEvent(nevent);
460
- // レスポンス受信時にタイムスタンプを更新
461
- this.lastResponseTime = Date.now();
462
296
  // we're only implementing client-side rpc
463
297
  if (!(parsedEvent as NDKRpcRequest).method) {
464
298
  console.log('parsed response', parsedEvent);
@@ -471,11 +305,6 @@ export class IframeNostrRpc extends NostrRpc {
471
305
  }
472
306
 
473
307
  public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise<NDKRpcResponse> {
474
- // リクエスト送信前に接続を確認 (relayを使用する場合に備えて)
475
- if (!this.iframePort) {
476
- await ensureNIP46Connection(this._ndk, 5000);
477
- }
478
-
479
308
  const id = this.getId();
480
309
 
481
310
  // create and sign request event
@@ -539,17 +368,6 @@ export class ReadyListener {
539
368
  async wait(): Promise<any> {
540
369
  console.log(new Date(), 'waiting for', this.messages);
541
370
  const r = await this.promise;
542
- // NOTE: timer here doesn't help bcs it must be activated when
543
- // user "confirms", but that's happening on a different
544
- // origin and we can't really know.
545
- // await new Promise<any>((ok, err) => {
546
- // // 10 sec should be more than enough
547
- // setTimeout(() => err(new Date() + ' timeout for ' + this.message), 10000);
548
-
549
- // // if promise already resolved or will resolve in the future
550
- // this.promise.then(ok);
551
- // });
552
-
553
371
  console.log(new Date(), 'finished waiting for', this.messages, r);
554
372
  return r;
555
373
  }
@@ -558,29 +376,72 @@ export class ReadyListener {
558
376
  export class Nip46Signer extends NDKNip46Signer {
559
377
  private _userPubkey: string = '';
560
378
  private _rpc: IframeNostrRpc;
379
+ private lastPingTime: number = 0;
380
+ private pingCacheDuration: number = 30000; // 30秒
381
+ private _remotePubkey?: string;
561
382
 
562
383
  constructor(ndk: NDK, localSigner: PrivateKeySigner, signerPubkey: string, iframeOrigin?: string) {
563
384
  super(ndk, signerPubkey, localSigner);
564
385
 
565
386
  // override with our own rpc implementation
566
387
  this._rpc = new IframeNostrRpc(ndk, localSigner, iframeOrigin);
567
- this._rpc.setUseNip44(true); // !!this.params.optionsModal.dev);
388
+ this._rpc.setUseNip44(true);
568
389
  this._rpc.on('authUrl', (url: string) => {
569
390
  this.emit('authUrl', url);
570
391
  });
571
392
 
572
393
  this.rpc = this._rpc;
394
+ this._remotePubkey = signerPubkey;
573
395
  }
574
396
 
575
397
  get userPubkey() {
576
398
  return this._userPubkey;
577
399
  }
578
400
 
401
+ // Use a different name to avoid conflict with base class property
402
+ get remotePubkeyAccessor() {
403
+ return this._remotePubkey;
404
+ }
405
+
406
+ set remotePubkeyAccessor(value: string | undefined) {
407
+ this._remotePubkey = value;
408
+ }
409
+
410
+ // 接続確認(必要時のみping)
411
+ private async ensureConnection(retries: number = 2): Promise<void> {
412
+ if (!this._remotePubkey) return;
413
+
414
+ const now = Date.now();
415
+
416
+ // 最近ping成功していればスキップ
417
+ if (now - this.lastPingTime < this.pingCacheDuration) {
418
+ return;
419
+ }
420
+
421
+ for (let i = 0; i <= retries; i++) {
422
+ try {
423
+ await this._rpc.pingWithTimeout(this._remotePubkey, 10000);
424
+ this.lastPingTime = now;
425
+ console.log('Connection check OK');
426
+ return;
427
+ } catch (error) {
428
+ if (i === retries) {
429
+ console.error('Connection check failed after retries', error);
430
+ throw new Error('NIP-46 connection lost');
431
+ }
432
+
433
+ const delay = Math.min(1000 * Math.pow(2, i), 5000);
434
+ console.log(`Ping failed, retrying in ${delay}ms...`);
435
+ await new Promise(resolve => setTimeout(resolve, delay));
436
+ }
437
+ }
438
+ }
439
+
579
440
  private async setSignerPubkey(signerPubkey: string, sameAsUser: boolean = false) {
580
441
  console.log('setSignerPubkey', signerPubkey);
581
442
 
582
443
  // ensure it's set
583
- this.remotePubkey = signerPubkey;
444
+ this._remotePubkey = signerPubkey;
584
445
 
585
446
  // when we're sure it's known
586
447
  this._rpc.on(`iframeRestart-${signerPubkey}`, () => {
@@ -601,10 +462,10 @@ export class Nip46Signer extends NDKNip46Signer {
601
462
 
602
463
  this._userPubkey = await withTimeout(
603
464
  new Promise<string>((ok, err) => {
604
- if (!this.remotePubkey) throw new Error('Signer pubkey not set');
465
+ if (!this._remotePubkey) throw new Error('Signer pubkey not set');
605
466
 
606
- console.log('get_public_key', this.remotePubkey);
607
- this._rpc.sendRequest(this.remotePubkey, 'get_public_key', [], 24133, (response: NDKRpcResponse) => {
467
+ console.log('get_public_key', this._remotePubkey);
468
+ this._rpc.sendRequest(this._remotePubkey, 'get_public_key', [], 24133, (response: NDKRpcResponse) => {
608
469
  if (response.error) {
609
470
  err(new Error(response.error));
610
471
  } else {
@@ -620,17 +481,42 @@ export class Nip46Signer extends NDKNip46Signer {
620
481
  public async listen(nostrConnectSecret: string) {
621
482
  const signerPubkey = await (this.rpc as IframeNostrRpc).listen(nostrConnectSecret);
622
483
  await this.setSignerPubkey(signerPubkey);
484
+
485
+ // ログイン完了後に接続確認
486
+ await this.ensureConnection();
623
487
  }
624
488
 
625
489
  public async connect(token?: string, perms?: string) {
626
- if (!this.remotePubkey) throw new Error('No signer pubkey');
627
- await (this._rpc as any).connectWithTimeout(this.remotePubkey, token, perms, NIP46_CONNECT_TIMEOUT);
628
- await this.setSignerPubkey(this.remotePubkey);
490
+ if (!this._remotePubkey) throw new Error('No signer pubkey');
491
+ await this._rpc.connectWithTimeout(this._remotePubkey, token, perms, NIP46_CONNECT_TIMEOUT);
492
+ await this.setSignerPubkey(this._remotePubkey);
493
+
494
+ // ログイン完了後に接続確認
495
+ await this.ensureConnection();
629
496
  }
630
497
 
631
498
  public async setListenReply(reply: any, nostrConnectSecret: string) {
632
499
  const signerPubkey = await this._rpc.parseNostrConnectReply(reply, nostrConnectSecret);
633
500
  await this.setSignerPubkey(signerPubkey, true);
501
+
502
+ // ログイン完了後に接続確認
503
+ await this.ensureConnection();
504
+ }
505
+
506
+ // 署名メソッドのオーバーライド - 署名前に接続確認
507
+ async sign(event: NostrEvent): Promise<string> {
508
+ await this.ensureConnection();
509
+ return super.sign(event);
510
+ }
511
+
512
+ async encrypt(recipient: NDKUser, value: string): Promise<string> {
513
+ await this.ensureConnection();
514
+ return super.encrypt(recipient, value);
515
+ }
516
+
517
+ async decrypt(sender: NDKUser, value: string): Promise<string> {
518
+ await this.ensureConnection();
519
+ return super.decrypt(sender, value);
634
520
  }
635
521
 
636
522
  public async createAccount2({ bunkerPubkey, name, domain, perms = '' }: { bunkerPubkey: string; name: string; domain: string; perms?: string }) {
@@ -652,4 +538,12 @@ export class Nip46Signer extends NDKNip46Signer {
652
538
 
653
539
  return r.result;
654
540
  }
655
- }
541
+
542
+ // EventEmitter互換メソッド
543
+ public override emit = <EventKey extends string | symbol = string>(
544
+ event: EventKey,
545
+ ...args: any[]
546
+ ): boolean => {
547
+ return this._rpc.emit(event as string, ...args);
548
+ }
549
+ }
@@ -1,7 +1,6 @@
1
1
  import { NDKPrivateKeySigner, NDKUser } from '@nostr-dev-kit/ndk';
2
2
  import { Nip44 } from '../utils/nip44';
3
3
  import { getPublicKey } from 'nostr-tools';
4
- import { hexToBytes } from 'nostr-tools/lib/types/utils';
5
4
 
6
5
  export class PrivateKeySigner extends NDKPrivateKeySigner {
7
6
  private nip44: Nip44 = new Nip44();
@@ -9,7 +8,7 @@ export class PrivateKeySigner extends NDKPrivateKeySigner {
9
8
 
10
9
  constructor(privateKey: string) {
11
10
  super(privateKey);
12
- this._pubkey = getPublicKey(hexToBytes(privateKey));
11
+ this._pubkey = getPublicKey(privateKey);
13
12
  }
14
13
 
15
14
  get pubkey() {
@@ -1,8 +1,7 @@
1
1
  import { Info, RecentType } from 'nostr-login-components/dist/types/types';
2
2
  import NDK, { NDKEvent, NDKRelaySet, NDKSigner, NDKUser } from '@nostr-dev-kit/ndk';
3
- import { generateSecretKey } from 'nostr-tools';
3
+ import { generatePrivateKey } from 'nostr-tools';
4
4
  import { NostrLoginOptions } from '../types';
5
- import { bytesToHex } from 'nostr-tools/lib/types/utils';
6
5
 
7
6
  const LOCAL_STORE_KEY = '__nostrlogin_nip46';
8
7
  const LOGGED_IN_ACCOUNTS = '__nostrlogin_accounts';
@@ -20,7 +19,7 @@ export const localStorageGetItem = (key: string) => {
20
19
  if (value) {
21
20
  try {
22
21
  return JSON.parse(value);
23
- } catch { }
22
+ } catch {}
24
23
  }
25
24
 
26
25
  return null;
@@ -93,7 +92,7 @@ export const bunkerUrlToInfo = (bunkerUrl: string, sk = ''): Info => {
93
92
  return {
94
93
  pubkey: '',
95
94
  signerPubkey: url.hostname || url.pathname.split('//')[1],
96
- sk: sk || bytesToHex(generateSecretKey()),
95
+ sk: sk || generatePrivateKey(),
97
96
  relays: url.searchParams.getAll('relay'),
98
97
  token: url.searchParams.get('secret') || '',
99
98
  authMethod: 'connect',
@@ -166,7 +165,7 @@ export const checkNip05 = async (nip05: string) => {
166
165
  pubkey = d.names[name];
167
166
  return;
168
167
  }
169
- } catch { }
168
+ } catch {}
170
169
 
171
170
  available = true;
172
171
  })();
@@ -10,7 +10,6 @@ import { sha256 } from "@noble/hashes/sha256"
10
10
  import { hmac } from "@noble/hashes/hmac";
11
11
  import { base64 } from "@scure/base";
12
12
  import { getPublicKey } from 'nostr-tools'
13
- import { hexToBytes } from "nostr-tools/lib/types/utils";
14
13
 
15
14
  // from https://github.com/nbd-wtf/nostr-tools
16
15
 
@@ -165,7 +164,7 @@ export class Nip44 {
165
164
  }
166
165
 
167
166
  private getKey(privkey: string, pubkey: string, extractable?: boolean) {
168
- const id = getPublicKey(hexToBytes(privkey)) + pubkey
167
+ const id = getPublicKey(privkey) + pubkey
169
168
  let cryptoKey = this.cache.get(id)
170
169
  if (cryptoKey) return cryptoKey
171
170