@konemono/nostr-login 1.15.6 → 1.15.8

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.
@@ -19,6 +19,7 @@ export declare const checkNip05: (nip05: string) => Promise<{
19
19
  }>;
20
20
  export declare const localStorageAddAccount: (info: Info) => void;
21
21
  export declare const localStorageRemoveCurrentAccount: () => void;
22
+ export declare const localStorageRemoveAccount: (user: Info) => void;
22
23
  export declare const localStorageRemoveRecent: (user: RecentType) => void;
23
24
  export declare const localStorageGetRecents: () => RecentType[];
24
25
  export declare const localStorageGetAccounts: () => Info[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konemono/nostr-login",
3
- "version": "1.15.6",
3
+ "version": "1.15.8",
4
4
  "description": "Extended fork of nostr-login with multi-relay support, QR scanner, and improved stability",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "tseep": "^1.2.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@konemono/nostr-login-components": "^1.4.6",
30
+ "@konemono/nostr-login-components": "^1.4.8",
31
31
  "@rollup/plugin-commonjs": "^25.0.7",
32
32
  "@rollup/plugin-node-resolve": "^15.2.3",
33
33
  "@rollup/plugin-terser": "^0.4.4",
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import '@konemono/nostr-login-components';
2
2
  import { AuthNostrService, NostrExtensionService, Popup, NostrParams, Nostr, ProcessManager, BannerManager, ModalManager } from './modules';
3
3
  import { NostrLoginAuthOptions, NostrLoginOptions, StartScreens } from './types';
4
- import { localStorageGetAccounts, localStorageGetCurrent, localStorageGetRecents, localStorageSetItem } from './utils';
4
+ import { localStorageGetAccounts, localStorageGetCurrent, localStorageGetRecents, localStorageRemoveAccount, localStorageSetItem } from './utils';
5
5
  import { Info } from '@konemono/nostr-login-components/dist/types/types';
6
6
  import { NostrObjectParams } from './modules/Nostr';
7
7
 
@@ -105,6 +105,10 @@ export class NostrLoginInitializer {
105
105
  this.switchAccount(info);
106
106
  });
107
107
 
108
+ this.modalManager.on('onRemoveAccount', async (info: Info) => {
109
+ this.removeAccount(info);
110
+ });
111
+
108
112
  this.modalManager.on('onLogoutBanner', async (info: Info) => {
109
113
  logout();
110
114
  });
@@ -129,6 +133,10 @@ export class NostrLoginInitializer {
129
133
  this.switchAccount(info);
130
134
  });
131
135
 
136
+ this.bannerManager.on('onRemoveAccount', async (info: Info) => {
137
+ this.removeAccount(info);
138
+ });
139
+
132
140
  this.bannerManager.on('import', () => {
133
141
  this.launch('import');
134
142
  });
@@ -181,6 +189,19 @@ export class NostrLoginInitializer {
181
189
  }
182
190
  }
183
191
 
192
+ private async removeAccount(info: Info) {
193
+ const current = this.params.userInfo || localStorageGetCurrent();
194
+ const isCurrent = current?.pubkey === info.pubkey && current?.authMethod === info.authMethod;
195
+
196
+ if (isCurrent) {
197
+ await this.logout();
198
+ return;
199
+ }
200
+
201
+ localStorageRemoveAccount(info);
202
+ this.updateAccounts();
203
+ }
204
+
184
205
  private updateAccounts() {
185
206
  const accounts = localStorageGetAccounts();
186
207
  const recents = localStorageGetRecents();
@@ -292,10 +292,9 @@ class AuthNostrService extends EventEmitter implements Signer {
292
292
  a.iframeUrl = info.nip46.iframe_url || '';
293
293
  // サービス固有のリレーがあればURLを再構築
294
294
  if (fetchedRelays && fetchedRelays.length && (!customRelays || customRelays.length === 0)) {
295
- const serviceNostrconnect = this.replaceRelayHints(nostrconnect, fetchedRelays);
296
- a.link = a.iframeUrl ? serviceNostrconnect : a.link;
297
- } else {
298
- a.link = a.iframeUrl ? nostrconnect : a.link;
295
+ a.link = this.replaceRelayHints(a.iframeUrl ? nostrconnect : a.link, fetchedRelays);
296
+ } else if (a.iframeUrl) {
297
+ a.link = nostrconnect;
299
298
  }
300
299
  a.available = true;
301
300
  } catch (e) {
@@ -311,13 +310,13 @@ class AuthNostrService extends EventEmitter implements Signer {
311
310
  }
312
311
 
313
312
  private replaceRelayHints(nostrconnectUrl: string, newRelays: string[]): string {
314
- // 既存のrelay=パラメータを除去して新しいリレーに置換
315
- const url = new URL(nostrconnectUrl);
316
- url.searchParams.delete('relay');
313
+ // 文字列操作でrelay=パラメータだけを置換(searchParams経由の再エンコードを回避)
314
+ const [base, query] = nostrconnectUrl.split('?');
315
+ const params = (query || '').split('&').filter(p => !p.startsWith('relay='));
317
316
  for (const r of newRelays) {
318
- url.searchParams.append('relay', r);
317
+ params.push(`relay=${encodeURIComponent(r)}`);
319
318
  }
320
- return url.toString();
319
+ return `${base}?${params.join('&')}`;
321
320
  }
322
321
 
323
322
  public async localSignup(name: string, sk?: string) {
@@ -735,7 +734,7 @@ class AuthNostrService extends EventEmitter implements Signer {
735
734
  if (iframeUrl) info.iframeUrl = iframeUrl;
736
735
 
737
736
  // カスタムリレーが指定されていれば使用する
738
- if (customRelays && customRelays.length > 0) {
737
+ if ((!info.relays || info.relays.length === 0) && customRelays && customRelays.length > 0) {
739
738
  info.relays = customRelays;
740
739
  }
741
740
 
@@ -130,6 +130,10 @@ class BannerManager extends EventEmitter {
130
130
  this.emit('onSwitchAccount', event.detail);
131
131
  });
132
132
 
133
+ this.banner.addEventListener('nlRemoveAccount', (event: any) => {
134
+ this.emit('onRemoveAccount', event.detail);
135
+ });
136
+
133
137
  this.banner.addEventListener('nlOpenWelcomeModal', () => {
134
138
  this.emit('launch');
135
139
 
@@ -492,6 +492,10 @@ class ModalManager extends EventEmitter {
492
492
  this.emit('updateAccounts');
493
493
  });
494
494
 
495
+ this.modal.addEventListener('nlRemoveAccount', (event: any) => {
496
+ this.emit('onRemoveAccount', event.detail as Info);
497
+ });
498
+
495
499
  const nameToPubkey = async (nameNpub: string) => {
496
500
  let pubkey = '';
497
501
  if (nameNpub.includes('@')) {
@@ -303,6 +303,48 @@ export const localStorageRemoveCurrentAccount = () => {
303
303
  localStorageRemoveItem(LOCAL_STORE_KEY);
304
304
  };
305
305
 
306
+ export const localStorageRemoveAccount = (user: Info) => {
307
+ if (!user) return;
308
+
309
+ upgradeInfo(user);
310
+
311
+ const current: Info | null = localStorageGetItem(LOCAL_STORE_KEY);
312
+ if (current) upgradeInfo(current);
313
+
314
+ const recentUser: RecentType = { ...user };
315
+ delete (recentUser as Record<string, unknown>)['sk'];
316
+ delete (recentUser as Record<string, unknown>)['otpData'];
317
+
318
+ const loggedInAccounts: Info[] = localStorageGetItem(LOGGED_IN_ACCOUNTS) || [];
319
+ const recentsAccounts: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || [];
320
+
321
+ loggedInAccounts.forEach(a => upgradeInfo(a));
322
+ recentsAccounts.forEach(a => upgradeInfo(a));
323
+
324
+ const accounts = loggedInAccounts.filter(el => el.pubkey !== user.pubkey || el.authMethod !== user.authMethod);
325
+ const recents: RecentType[] = recentsAccounts;
326
+
327
+ if (recentUser.authMethod === 'connect' && recentUser.bunkerUrl && recentUser.bunkerUrl.includes('secret=')) {
328
+ console.log('nostr login bunker conn with a secret not saved to recent');
329
+ } else if (recentUser.authMethod === 'local') {
330
+ console.log('nostr login temporary local keys not save to recent');
331
+ } else {
332
+ const index = recentsAccounts.findIndex((el: RecentType) => el.pubkey === recentUser.pubkey && el.authMethod === recentUser.authMethod);
333
+ if (index !== -1) {
334
+ recents[index] = recentUser;
335
+ } else {
336
+ recents.push(recentUser);
337
+ }
338
+ }
339
+
340
+ localStorageSetItem(RECENT_ACCOUNTS, JSON.stringify(recents));
341
+ localStorageSetItem(LOGGED_IN_ACCOUNTS, JSON.stringify(accounts));
342
+
343
+ if (current && current.pubkey === user.pubkey && current.authMethod === user.authMethod) {
344
+ localStorageRemoveItem(LOCAL_STORE_KEY);
345
+ }
346
+ };
347
+
306
348
  export const localStorageRemoveRecent = (user: RecentType) => {
307
349
  const recentsAccounts: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || [];
308
350
  recentsAccounts.forEach(a => upgradeInfo(a));