@konemono/nostr-login 1.7.49 → 1.7.51

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.
@@ -2,7 +2,7 @@ export declare function encryptNip44(plaintext: string, conversationKey: Uint8Ar
2
2
  export declare function decryptNip44(payload: string, conversationKey: Uint8Array): string;
3
3
  export declare class Nip44 {
4
4
  private cache;
5
- createKey(privkey: string, pubkey: string): Uint8Array<ArrayBufferLike>;
5
+ createKey(privkey: string, pubkey: string): Uint8Array;
6
6
  private getKey;
7
7
  encrypt(privkey: string, pubkey: string, text: string): string;
8
8
  decrypt(privkey: string, pubkey: string, data: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konemono/nostr-login",
3
- "version": "1.7.49",
3
+ "version": "1.7.51",
4
4
  "description": "",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,17 +11,17 @@
11
11
  },
12
12
  "author": "a-fralou",
13
13
  "dependencies": {
14
- "@nostr-dev-kit/ndk": "^2.18.1",
14
+ "@nostr-dev-kit/ndk": "^2.3.1",
15
15
  "nostr-tools": "^1.17.0",
16
- "tseep": "^1.3.1"
16
+ "tseep": "^1.2.1"
17
17
  },
18
18
  "devDependencies": {
19
- "@rollup/plugin-commonjs": "^25.0.8",
20
- "@rollup/plugin-node-resolve": "^15.3.1",
19
+ "@rollup/plugin-commonjs": "^25.0.7",
20
+ "@rollup/plugin-node-resolve": "^15.2.3",
21
21
  "@rollup/plugin-terser": "^0.4.4",
22
22
  "nostr-login-components": "^1.0.3",
23
- "prettier": "^3.7.4",
24
- "rollup": "^4.53.5",
23
+ "prettier": "^3.2.2",
24
+ "rollup": "^4.9.6",
25
25
  "rollup-plugin-typescript2": "^0.36.0"
26
26
  },
27
27
  "license": "MIT"
@@ -0,0 +1,106 @@
1
+ import { NDKUser } from '@nostr-dev-kit/ndk';
2
+ import { Signer } from './Nostr';
3
+
4
+ export class AmberDirectSigner implements Signer {
5
+ private _pubkey: string = '';
6
+
7
+ constructor(pubkey?: string) {
8
+ this._pubkey = pubkey || '';
9
+ }
10
+
11
+ get pubkey() {
12
+ return this._pubkey;
13
+ }
14
+
15
+ public set pubkey(v: string) {
16
+ this._pubkey = v;
17
+ }
18
+
19
+ nip04 = {
20
+ encrypt: (pubkey: string, plaintext: string) => this.encrypt04(pubkey, plaintext),
21
+ decrypt: (pubkey: string, ciphertext: string) => this.decrypt04(pubkey, ciphertext),
22
+ };
23
+
24
+ nip44 = {
25
+ encrypt: (pubkey: string, plaintext: string) => this.encrypt44(pubkey, plaintext),
26
+ decrypt: (pubkey: string, ciphertext: string) => this.decrypt44(pubkey, ciphertext),
27
+ };
28
+
29
+ async signEvent(event: any): Promise<any> {
30
+ const id = Math.random().toString(36).substring(7);
31
+ const url = this.generateUrl(JSON.stringify(event), 'sign_event', id);
32
+ window.location.href = url;
33
+ // This will never resolve because of page reload
34
+ return new Promise(() => {});
35
+ }
36
+
37
+ async encrypt04(pubkey: string, plaintext: string): Promise<string> {
38
+ const id = Math.random().toString(36).substring(7);
39
+ const url = this.generateUrl(plaintext, 'nip04_encrypt', id, pubkey);
40
+ window.location.href = url;
41
+ return new Promise(() => {});
42
+ }
43
+
44
+ async decrypt04(pubkey: string, ciphertext: string): Promise<string> {
45
+ const id = Math.random().toString(36).substring(7);
46
+ const url = this.generateUrl(ciphertext, 'nip04_decrypt', id, pubkey);
47
+ window.location.href = url;
48
+ return new Promise(() => {});
49
+ }
50
+
51
+ async encrypt44(pubkey: string, plaintext: string): Promise<string> {
52
+ const id = Math.random().toString(36).substring(7);
53
+ const url = this.generateUrl(plaintext, 'nip44_encrypt', id, pubkey);
54
+ window.location.href = url;
55
+ return new Promise(() => {});
56
+ }
57
+
58
+ async decrypt44(pubkey: string, ciphertext: string): Promise<string> {
59
+ const id = Math.random().toString(36).substring(7);
60
+ const url = this.generateUrl(ciphertext, 'nip44_decrypt', id, pubkey);
61
+ window.location.href = url;
62
+ return new Promise(() => {});
63
+ }
64
+
65
+ public async getPublicKey(): Promise<string> {
66
+ const id = Math.random().toString(36).substring(7);
67
+ const url = this.generateUrl('', 'get_public_key', id);
68
+ window.location.href = url;
69
+ return new Promise(() => {});
70
+ }
71
+
72
+ private generateUrl(content: string, type: string, id: string, recipient?: string): string {
73
+ const callbackUrl = new URL(window.location.href);
74
+ callbackUrl.searchParams.set('amberType', type);
75
+ callbackUrl.searchParams.set('amberId', id);
76
+
77
+ const params = new URLSearchParams();
78
+ params.set('type', type);
79
+ params.set('id', id);
80
+ params.set('callbackUrl', callbackUrl.toString());
81
+ if (this._pubkey) params.set('pubkey', this._pubkey);
82
+ if (recipient) params.set('pubkey', recipient); // Amber uses pubkey param for recipient in encrypt/decrypt
83
+
84
+ return `nostrsigner:${encodeURIComponent(content)}?${params.toString()}`;
85
+ }
86
+
87
+ public static parseResponse(): { type: string; id: string; result: string } | null {
88
+ const params = new URLSearchParams(window.location.search);
89
+ const type = params.get('amberType');
90
+ const id = params.get('amberId');
91
+ const result = params.get('signature') || params.get('result'); // Amber uses signature for events, result for others?
92
+
93
+ if (type && id && result) {
94
+ // Clean up URL
95
+ const newUrl = new URL(window.location.href);
96
+ newUrl.searchParams.delete('amberType');
97
+ newUrl.searchParams.delete('amberId');
98
+ newUrl.searchParams.delete('signature');
99
+ newUrl.searchParams.delete('result');
100
+ window.history.replaceState({}, '', newUrl.toString());
101
+
102
+ return { type, id, result };
103
+ }
104
+ return null;
105
+ }
106
+ }
@@ -1,19 +1,20 @@
1
- //AuthNostrService.ts
2
1
  import { localStorageAddAccount, bunkerUrlToInfo, isBunkerUrl, fetchProfile, getBunkerUrl, localStorageRemoveCurrentAccount, createProfile, getIcon } from '../utils';
3
2
  import { ConnectionString, Info } from 'nostr-login-components/dist/types/types';
4
3
  import { generatePrivateKey, getEventHash, getPublicKey, nip19 } from 'nostr-tools';
5
4
  import { NostrLoginAuthOptions, Response } from '../types';
6
- import NDK, { NDKEvent, NDKNip46Signer, NDKPrivateKeySigner, NDKRpcResponse, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk';
5
+ import NDK, { NDKEvent, NDKNip46Signer, NDKRpcResponse, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk';
7
6
  import { NostrParams } from './';
8
7
  import { EventEmitter } from 'tseep';
9
8
  import { Signer } from './Nostr';
10
9
  import { Nip44 } from '../utils/nip44';
11
10
  import { IframeNostrRpc, Nip46Signer, ReadyListener } from './Nip46';
12
- //import { PrivateKeySigner } from './Signer';
11
+ import { PrivateKeySigner } from './Signer';
12
+ import { AmberDirectSigner } from './AmberDirectSigner';
13
+
13
14
 
14
15
  const OUTBOX_RELAYS = ['wss://user.kindpag.es', 'wss://purplepag.es', 'wss://relay.nos.social'];
15
16
  const DEFAULT_NOSTRCONNECT_RELAYS = ['wss://relay.nsec.app/', 'wss://ephemeral.snowflare.cc/'];
16
- const CONNECT_TIMEOUT = 20000;
17
+ const CONNECT_TIMEOUT = 5000;
17
18
  const NOSTRCONNECT_APPS: ConnectionString[] = [
18
19
  {
19
20
  name: 'Nsec.app',
@@ -41,7 +42,8 @@ class AuthNostrService extends EventEmitter implements Signer {
41
42
  private ndk: NDK;
42
43
  private profileNdk: NDK;
43
44
  private signer: Nip46Signer | null = null;
44
- private localSigner: NDKPrivateKeySigner | null = null;
45
+ private amberSigner: AmberDirectSigner | null = null;
46
+ private localSigner: PrivateKeySigner | null = null;
45
47
  private params: NostrParams;
46
48
  private signerPromise?: Promise<void>;
47
49
  private signerErrCallback?: (err: string) => void;
@@ -83,6 +85,31 @@ class AuthNostrService extends EventEmitter implements Signer {
83
85
  encrypt: this.encrypt44.bind(this),
84
86
  decrypt: this.decrypt44.bind(this),
85
87
  };
88
+
89
+ this.checkAmberResponse();
90
+ }
91
+
92
+ private checkAmberResponse() {
93
+ const response = AmberDirectSigner.parseResponse();
94
+ if (response) {
95
+ if (response.type === 'get_public_key') {
96
+ const info: Info = {
97
+ pubkey: response.result,
98
+ authMethod: 'amber' as any,
99
+ };
100
+ this.onAuth('login', info);
101
+ } else {
102
+ // For other types, we might want to store the result in a way
103
+ // that the next call to the same method can return it immediately
104
+ // but for now, we just log it.
105
+ console.log('Amber response', response);
106
+ if (response.type === 'sign_event') {
107
+ // If it's a signed event, we could potentially use it if someone asks for it.
108
+ // But usually the app will re-request signing.
109
+ // A better way would be to have a session-based cache.
110
+ }
111
+ }
112
+ }
86
113
  }
87
114
 
88
115
  public isIframe() {
@@ -93,13 +120,13 @@ class AuthNostrService extends EventEmitter implements Signer {
93
120
  if (this.signerPromise) {
94
121
  try {
95
122
  await this.signerPromise;
96
- } catch {}
123
+ } catch { }
97
124
  }
98
125
 
99
126
  if (this.readyPromise) {
100
127
  try {
101
128
  await this.readyPromise;
102
- } catch {}
129
+ } catch { }
103
130
  }
104
131
  }
105
132
 
@@ -124,6 +151,7 @@ class AuthNostrService extends EventEmitter implements Signer {
124
151
  ) {
125
152
  relays = relays && relays.length > 0 ? relays : DEFAULT_NOSTRCONNECT_RELAYS;
126
153
 
154
+
127
155
  const info: Info = {
128
156
  authMethod: 'connect',
129
157
  pubkey: '', // unknown yet!
@@ -137,7 +165,13 @@ class AuthNostrService extends EventEmitter implements Signer {
137
165
  console.log('nostrconnect info', info, link);
138
166
 
139
167
  // non-iframe flow
140
- if (link && !iframeUrl) window.open(link, '_blank', 'width=400,height=700');
168
+ if (link && !iframeUrl) {
169
+ if (link === 'amber') {
170
+ const signer = new AmberDirectSigner();
171
+ return (signer as any).getPublicKey(); // will redirect
172
+ }
173
+ window.open(link, '_blank', 'width=400,height=700');
174
+ }
141
175
 
142
176
  // init nip46 signer
143
177
  await this.initSigner(info, { listen: true });
@@ -154,6 +188,13 @@ class AuthNostrService extends EventEmitter implements Signer {
154
188
  }
155
189
 
156
190
  public async createNostrConnect(relays?: string[]) {
191
+ /*const relayList = relays
192
+ ? relays
193
+ .split(",")
194
+ .map(r => r.trim().replace(/['"]/g, ""))
195
+ .filter(r => r.length > 0)
196
+ : [];*/
197
+
157
198
  this.nostrConnectKey = generatePrivateKey();
158
199
  this.nostrConnectSecret = Math.random().toString(36).substring(7);
159
200
 
@@ -165,16 +206,24 @@ class AuthNostrService extends EventEmitter implements Signer {
165
206
  perms: encodeURIComponent(this.params.optionsModal.perms || ''),
166
207
  };
167
208
 
168
- // .join('') を追加
169
- const relayParams = (relays || []).length > 0 ? (relays || []).map(r => `&relay=${encodeURIComponent(r)}`).join('') : '';
170
-
171
- return `nostrconnect://${pubkey}?image=${meta.icon}&url=${meta.url}&name=${meta.name}&perms=${meta.perms}&secret=${this.nostrConnectSecret}${relayParams}`;
209
+ return `nostrconnect://${pubkey}?image=${meta.icon}&url=${meta.url}&name=${meta.name}&perms=${meta.perms}&secret=${this.nostrConnectSecret}${(relays || []).length > 0 ? (relays || []).map((r, i) => `&relay=${r}`) : ""}`;
172
210
  }
173
211
 
174
212
  public async getNostrConnectServices(): Promise<[string, ConnectionString[]]> {
175
- const nostrconnect = await this.createNostrConnect(DEFAULT_NOSTRCONNECT_RELAYS);
213
+ const nostrconnect = await this.createNostrConnect();
176
214
 
215
+ // copy defaults
177
216
  const apps = NOSTRCONNECT_APPS.map(a => ({ ...a }));
217
+ // if (this.params.optionsModal.dev) {
218
+ // apps.push({
219
+ // name: 'Dev.Nsec.app',
220
+ // domain: 'new.nsec.app',
221
+ // canImport: true,
222
+ // img: 'https://new.nsec.app/assets/favicon.ico',
223
+ // link: 'https://dev.nsec.app/<nostrconnect>',
224
+ // relay: 'wss://relay.nsec.app/',
225
+ // });
226
+ // }
178
227
 
179
228
  for (const a of apps) {
180
229
  let relays: string[] = [...DEFAULT_NOSTRCONNECT_RELAYS];
@@ -196,12 +245,18 @@ class AuthNostrService extends EventEmitter implements Signer {
196
245
  }
197
246
  }
198
247
 
199
- // nostrconnectから既存のリレーを削除して新しいリレーを追加
200
- const baseUrl = nostrconnect.split('&relay=')[0];
201
- const relayParams = relays.map(r => `&relay=${encodeURIComponent(r)}`).join('');
202
- const nc = baseUrl + relayParams;
248
+ const relayParams = relays
249
+ .map(r => r.replace(/['"]/g, ''))
250
+ .map(r => `&relay=${encodeURIComponent(r)}`)
251
+ .join('');
252
+
253
+ const nc = nostrconnect + relayParams;
203
254
 
204
- a.link = a.iframeUrl ? nc : a.link.replace('<nostrconnect>', nc);
255
+ if (a.iframeUrl) {
256
+ a.link = nc;
257
+ } else {
258
+ a.link = a.link.replace('<nostrconnect>', nc);
259
+ }
205
260
  }
206
261
 
207
262
  return [nostrconnect, apps];
@@ -223,7 +278,7 @@ class AuthNostrService extends EventEmitter implements Signer {
223
278
 
224
279
  public async setLocal(info: Info, signup?: boolean) {
225
280
  this.releaseSigner();
226
- this.localSigner = new NDKPrivateKeySigner(info.sk!);
281
+ this.localSigner = new PrivateKeySigner(info.sk!);
227
282
 
228
283
  if (signup) await createProfile(info, this.profileNdk, this.localSigner, this.params.optionsModal.signupRelays, this.params.optionsModal.outboxRelays);
229
284
 
@@ -278,6 +333,12 @@ class AuthNostrService extends EventEmitter implements Signer {
278
333
  await this.endAuth();
279
334
  }
280
335
 
336
+ public async setAmber(info: Info) {
337
+ this.releaseSigner();
338
+ this.amberSigner = new AmberDirectSigner(info.pubkey);
339
+ this.onAuth('login', info);
340
+ }
341
+
281
342
  public async createAccount(nip05: string) {
282
343
  const [name, domain] = nip05.split('@');
283
344
 
@@ -297,7 +358,9 @@ class AuthNostrService extends EventEmitter implements Signer {
297
358
  const userPubkey = await this.signer!.createAccount2({ bunkerPubkey: info.signerPubkey!, name, domain, perms: this.params.optionsModal.perms });
298
359
 
299
360
  return {
300
- bunkerUrl: `bunker://${userPubkey}?` + (info.relays ?? []).map((r: string) => `relay=${encodeURIComponent(r)}`).join('&'),
361
+ bunkerUrl:
362
+ `bunker://${userPubkey}?` +
363
+ (info.relays ?? []).map((r: string) => `relay=${encodeURIComponent(r)}`).join('&'),
301
364
  sk: info.sk,
302
365
  };
303
366
  }
@@ -306,6 +369,7 @@ class AuthNostrService extends EventEmitter implements Signer {
306
369
  this.signer = null;
307
370
  this.signerErrCallback?.('cancelled');
308
371
  this.localSigner = null;
372
+ this.amberSigner = null;
309
373
 
310
374
  // disconnect from signer relays
311
375
  for (const r of this.ndk.pool.relays.keys()) {
@@ -348,7 +412,7 @@ class AuthNostrService extends EventEmitter implements Signer {
348
412
  if (info && this.params.userInfo && (info.pubkey !== this.params.userInfo.pubkey || info.authMethod !== this.params.userInfo.authMethod)) {
349
413
  const event = new CustomEvent('nlAuth', { detail: { type: 'logout' } });
350
414
  console.log('nostr-login auth', event.detail);
351
- document.dispatchEvent(event);
415
+ document.dispatchEvent(event)
352
416
  }
353
417
 
354
418
  this.setUserInfo(info);
@@ -485,7 +549,7 @@ class AuthNostrService extends EventEmitter implements Signer {
485
549
  }
486
550
 
487
551
  public async startAuth() {
488
- console.log('startAuth');
552
+ console.log("startAuth");
489
553
  if (this.readyCallback) throw new Error('Already started');
490
554
 
491
555
  // start the new promise
@@ -529,100 +593,81 @@ class AuthNostrService extends EventEmitter implements Signer {
529
593
  if (this.signerPromise) {
530
594
  try {
531
595
  await this.signerPromise;
532
- } catch {}
596
+ } catch { }
533
597
  }
534
598
 
599
+ // we remove support for iframe from nip05 and bunker-url methods,
600
+ // only nostrconnect flow will use it.
601
+ // info.iframeUrl = info.iframeUrl || (await this.getIframeUrl(info.domain));
535
602
  console.log('initSigner info', info);
536
603
 
604
+ // start listening for the ready signal
537
605
  const iframeOrigin = info.iframeUrl ? new URL(info.iframeUrl!).origin : undefined;
606
+ if (iframeOrigin) this.starterReady = new ReadyListener(['starterDone', 'starterError'], iframeOrigin);
538
607
 
539
- if (iframeOrigin) {
540
- this.starterReady = new ReadyListener(['starterDone', 'starterError'], iframeOrigin);
541
- }
542
-
608
+ // notify modals so they could show the starter iframe,
609
+ // FIXME shouldn't this come from nostrconnect service list?
543
610
  this.emit('onIframeUrl', info.iframeUrl);
544
611
 
545
612
  this.signerPromise = new Promise<void>(async (ok, err) => {
546
613
  this.signerErrCallback = err;
547
-
548
614
  try {
549
- console.log('NDK relays before connect:', Array.from(this.ndk.pool.relays.keys()));
550
-
615
+ // pre-connect if we're creating the connection (listen|connect) or
616
+ // not iframe mode
551
617
  if (info.relays && !info.iframeUrl) {
552
618
  for (const r of info.relays) {
553
619
  this.ndk.addExplicitRelay(r, undefined);
554
- console.log('Added relay:', r);
555
620
  }
556
621
  }
557
622
 
558
- console.log('NDK relays after add:', Array.from(this.ndk.pool.relays.keys()));
559
-
560
- // 接続開始(失敗しても続行)
561
- this.ndk.connect(CONNECT_TIMEOUT).then(value => {
562
- console.log(value);
563
- });
564
-
565
- // 少なくとも1つ接続されるのを待つ(致命扱いしない)
566
- await new Promise<void>(resolve => {
567
- const start = Date.now();
568
-
569
- const timer = setInterval(() => {
570
- const connected = this.ndk.pool.connectedRelays();
571
-
572
- if (connected.length > 0) {
573
- clearInterval(timer);
574
- resolve();
575
- return;
576
- }
577
-
578
- if (Date.now() - start > CONNECT_TIMEOUT) {
579
- // タイムアウトしても続行
580
- clearInterval(timer);
581
- resolve();
582
- }
583
- }, 3000);
584
- });
585
-
586
- console.log(
587
- 'NDK connected relays:',
588
- this.ndk.pool.connectedRelays().map(r => r.url),
589
- );
623
+ // wait until we connect, otherwise
624
+ // signer won't start properly
625
+ await this.ndk.connect(CONNECT_TIMEOUT);
590
626
 
591
- const localSigner = new NDKPrivateKeySigner(info.sk!);
627
+ // create and prepare the signer
628
+ const localSigner = new PrivateKeySigner(info.sk!);
592
629
  this.signer = new Nip46Signer(this.ndk, localSigner, info.signerPubkey!, iframeOrigin);
593
630
 
594
- this.signer.on('iframeRestart', async () => {
631
+ // we should notify the banner the same way as
632
+ // the onAuthUrl does
633
+ this.signer.on(`iframeRestart`, async () => {
595
634
  const iframeUrl = info.iframeUrl + (info.iframeUrl!.includes('?') ? '&' : '?') + 'pubkey=' + info.pubkey + '&rebind=' + localSigner.pubkey;
596
-
597
- this.emit('iframeRestart', {
598
- pubkey: info.pubkey,
599
- iframeUrl,
600
- });
635
+ this.emit('iframeRestart', { pubkey: info.pubkey, iframeUrl });
601
636
  });
602
637
 
638
+ // OAuth flow
639
+ // if (!listen) {
603
640
  this.signer.on('authUrl', (url: string) => {
604
641
  console.log('nostr login auth url', url);
605
- this.emit('onAuthUrl', {
606
- url,
607
- iframeUrl: info.iframeUrl,
608
- eventToAddAccount,
609
- });
642
+
643
+ // notify our UI
644
+ this.emit('onAuthUrl', { url, iframeUrl: info.iframeUrl, eventToAddAccount });
610
645
  });
646
+ // }
611
647
 
612
648
  if (listen) {
649
+ // nostrconnect: flow
650
+ // wait for the incoming message from signer
613
651
  await this.listen(info);
614
652
  } else if (connect) {
653
+ // bunker: flow
654
+ // send 'connect' message to signer
615
655
  await this.connect(info, this.params.optionsModal.perms);
616
656
  } else {
617
- await this.signer.initUserPubkey(info.pubkey);
657
+ // provide saved pubkey as a hint
658
+ await this.signer!.initUserPubkey(info.pubkey);
618
659
  }
619
660
 
620
- info.pubkey = this.signer.userPubkey!;
621
- info.signerPubkey = this.signer.remotePubkey;
661
+ // ensure, we're using it in callbacks above
662
+ // and expect info to be valid after this call
663
+ info.pubkey = this.signer!.userPubkey;
664
+ // learned after nostrconnect flow
665
+ info.signerPubkey = this.signer!.remotePubkey;
622
666
 
623
667
  ok();
624
668
  } catch (e) {
625
669
  console.log('initSigner failure', e);
670
+ // make sure signer isn't set
626
671
  this.signer = null;
627
672
  err(e);
628
673
  }
@@ -674,6 +719,10 @@ class AuthNostrService extends EventEmitter implements Signer {
674
719
  event.pubkey = getPublicKey(this.localSigner.privateKey!);
675
720
  event.id = getEventHash(event);
676
721
  event.sig = await this.localSigner.sign(event);
722
+ } else if (this.params.userInfo?.authMethod === ('amber' as any)) {
723
+ const userInfo = this.params.userInfo!;
724
+ if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
725
+ return this.amberSigner.signEvent(event);
677
726
  } else {
678
727
  event.pubkey = this.signer?.remotePubkey;
679
728
  event.id = getEventHash(event);
@@ -706,6 +755,10 @@ class AuthNostrService extends EventEmitter implements Signer {
706
755
  public async encrypt04(pubkey: string, plaintext: string) {
707
756
  if (this.localSigner) {
708
757
  return this.localSigner.encrypt(new NDKUser({ pubkey }), plaintext);
758
+ } else if (this.params.userInfo?.authMethod === ('amber' as any)) {
759
+ const userInfo = this.params.userInfo!;
760
+ if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
761
+ return this.amberSigner.encrypt04(pubkey, plaintext);
709
762
  } else {
710
763
  return this.signer!.encrypt(new NDKUser({ pubkey }), plaintext);
711
764
  }
@@ -714,6 +767,10 @@ class AuthNostrService extends EventEmitter implements Signer {
714
767
  public async decrypt04(pubkey: string, ciphertext: string) {
715
768
  if (this.localSigner) {
716
769
  return this.localSigner.decrypt(new NDKUser({ pubkey }), ciphertext);
770
+ } else if (this.params.userInfo?.authMethod === ('amber' as any)) {
771
+ const userInfo = this.params.userInfo!;
772
+ if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
773
+ return this.amberSigner.decrypt04(pubkey, ciphertext);
717
774
  } else {
718
775
  // decrypt is broken in ndk v2.3.1, and latest
719
776
  // ndk v2.8.1 doesn't allow to override connect easily,
@@ -726,6 +783,10 @@ class AuthNostrService extends EventEmitter implements Signer {
726
783
  public async encrypt44(pubkey: string, plaintext: string) {
727
784
  if (this.localSigner) {
728
785
  return this.nip44Codec.encrypt(this.localSigner.privateKey!, pubkey, plaintext);
786
+ } else if (this.params.userInfo?.authMethod === ('amber' as any)) {
787
+ const userInfo = this.params.userInfo!;
788
+ if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
789
+ return this.amberSigner.encrypt44(pubkey, plaintext);
729
790
  } else {
730
791
  // no support of nip44 in ndk yet
731
792
  return this.codec_call('nip44_encrypt', pubkey, plaintext);
@@ -735,6 +796,10 @@ class AuthNostrService extends EventEmitter implements Signer {
735
796
  public async decrypt44(pubkey: string, ciphertext: string) {
736
797
  if (this.localSigner) {
737
798
  return this.nip44Codec.decrypt(this.localSigner.privateKey!, pubkey, ciphertext);
799
+ } else if (this.params.userInfo?.authMethod === ('amber' as any)) {
800
+ const userInfo = this.params.userInfo!;
801
+ if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
802
+ return this.amberSigner.decrypt44(pubkey, ciphertext);
738
803
  } else {
739
804
  // no support of nip44 in ndk yet
740
805
  return this.codec_call('nip44_decrypt', pubkey, ciphertext);
@@ -402,6 +402,9 @@ class ModalManager extends EventEmitter {
402
402
  } else if (userInfo.authMethod === 'extension') {
403
403
  await this.extensionService.trySetExtensionForPubkey(userInfo.pubkey);
404
404
  dialog.close();
405
+ } else if (userInfo.authMethod === ('amber' as any)) {
406
+ this.authNostrService.setAmber(userInfo);
407
+ dialog.close();
405
408
  } else {
406
409
  const input = userInfo.bunkerUrl || userInfo.nip05;
407
410
  if (!input) throw new Error('Bad connect info');