@konemono/nostr-login 1.9.6 → 1.9.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.
- package/dist/index.esm.js +4 -4
- package/dist/modules/AuthNostrService.d.ts +0 -4
- package/dist/unpkg.js +4 -4
- package/package.json +1 -1
- package/src/modules/AuthNostrService.ts +11 -150
package/package.json
CHANGED
|
@@ -11,7 +11,6 @@ import { IframeNostrRpc, Nip46Signer, ReadyListener, RpcResponse } from './Nip46
|
|
|
11
11
|
import { Nip46Client } from './nip46/Nip46Client';
|
|
12
12
|
import { Nip46Adapter } from './nip46/Nip46Adapter';
|
|
13
13
|
import { PrivateKeySigner } from './Signer';
|
|
14
|
-
import { AmberDirectSigner } from './AmberDirectSigner';
|
|
15
14
|
|
|
16
15
|
const OUTBOX_RELAYS = ['wss://user.kindpag.es', 'wss://purplepag.es', 'wss://relay.nos.social'];
|
|
17
16
|
const DEFAULT_NOSTRCONNECT_RELAYS = ['wss://relay.nsec.app/', 'wss://ephemeral.snowflare.cc/'];
|
|
@@ -41,7 +40,6 @@ const NOSTRCONNECT_APPS: ConnectionString[] = [
|
|
|
41
40
|
|
|
42
41
|
class AuthNostrService extends EventEmitter implements Signer {
|
|
43
42
|
private signer: any = null;
|
|
44
|
-
private amberSigner: AmberDirectSigner | null = null;
|
|
45
43
|
private localSigner: PrivateKeySigner | null = null;
|
|
46
44
|
private params: NostrParams;
|
|
47
45
|
private signerPromise?: Promise<void>;
|
|
@@ -75,97 +73,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
75
73
|
encrypt: this.encrypt44.bind(this),
|
|
76
74
|
decrypt: this.decrypt44.bind(this),
|
|
77
75
|
};
|
|
78
|
-
|
|
79
|
-
setTimeout(() => this.checkAmberResponse(), 100);
|
|
80
|
-
|
|
81
|
-
const check = () => {
|
|
82
|
-
this.checkAmberResponse();
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
window.addEventListener('focus', check);
|
|
86
|
-
window.addEventListener('visibilitychange', () => {
|
|
87
|
-
if (document.visibilityState === 'visible') check();
|
|
88
|
-
});
|
|
89
|
-
window.addEventListener('popstate', check);
|
|
90
|
-
window.addEventListener('hashchange', check);
|
|
91
|
-
|
|
92
|
-
// Periodic check as a safety net
|
|
93
|
-
setInterval(check, 1000);
|
|
94
|
-
|
|
95
|
-
window.addEventListener('message', event => {
|
|
96
|
-
if (event.data && event.data.method === 'amberResponse') {
|
|
97
|
-
const { id, type, result } = event.data;
|
|
98
|
-
console.log('Amber response received via message', { id, type, result });
|
|
99
|
-
this.handleAmberResponse({ id, type, result });
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private checkAmberResponse() {
|
|
105
|
-
const response = AmberDirectSigner.parseResponse();
|
|
106
|
-
if (response) {
|
|
107
|
-
// If we have an opener and it's not the same window, we are in a popup
|
|
108
|
-
if (window.opener && window.opener !== window) {
|
|
109
|
-
console.log('Amber response in popup, sending back to opener');
|
|
110
|
-
window.opener.postMessage({ method: 'amberResponse', ...response }, window.location.origin);
|
|
111
|
-
window.close();
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this.handleAmberResponse(response);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private handledAmberIds: Set<string> = new Set();
|
|
120
|
-
|
|
121
|
-
private handleAmberResponse(response: { id: string; type: string; result: string }) {
|
|
122
|
-
if (this.handledAmberIds.has(response.id)) return;
|
|
123
|
-
this.handledAmberIds.add(response.id);
|
|
124
|
-
|
|
125
|
-
console.log('Handling Amber response', response);
|
|
126
|
-
|
|
127
|
-
// Stop the "Connecting..." spinner
|
|
128
|
-
this.emit('onAuthUrl', { url: '' });
|
|
129
|
-
|
|
130
|
-
// Resolve pending promises if any (for non-reload cases)
|
|
131
|
-
const resolved = AmberDirectSigner.resolvePending(response.id, response.type, response.result);
|
|
132
|
-
if (resolved) {
|
|
133
|
-
console.log('Resolved pending Amber promise via resolvePending');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (response.type === 'get_public_key' || response.type.includes('pub')) {
|
|
137
|
-
const info: Info = {
|
|
138
|
-
pubkey: response.result,
|
|
139
|
-
name: nip19.npubEncode(response.result),
|
|
140
|
-
authMethod: 'amber' as any,
|
|
141
|
-
relays: [],
|
|
142
|
-
signerPubkey: '',
|
|
143
|
-
};
|
|
144
|
-
console.log('Amber login success', info);
|
|
145
|
-
this.emit('onUserInfo', info);
|
|
146
|
-
this.onAuth('login', info);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// URLクリーンアップをより徹底的に
|
|
150
|
-
const url = new URL(window.location.href);
|
|
151
|
-
let changed = false;
|
|
152
|
-
if (url.searchParams.has('event')) {
|
|
153
|
-
url.searchParams.delete('event');
|
|
154
|
-
changed = true;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// パス末尾が結果と一致する場合はパスもクリア
|
|
158
|
-
const pathParts = url.pathname.split('/');
|
|
159
|
-
if (pathParts.length > 0 && pathParts[pathParts.length - 1] === response.result) {
|
|
160
|
-
pathParts.pop();
|
|
161
|
-
url.pathname = pathParts.join('/') || '/';
|
|
162
|
-
changed = true;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (changed) {
|
|
166
|
-
console.log('Cleaning up Amber response URL', url.toString());
|
|
167
|
-
window.history.replaceState({}, '', url.toString());
|
|
168
|
-
}
|
|
169
76
|
}
|
|
170
77
|
|
|
171
78
|
public isIframe() {
|
|
@@ -219,44 +126,16 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
219
126
|
|
|
220
127
|
console.log('nostrconnect info', info, link);
|
|
221
128
|
|
|
222
|
-
// non-iframe flow
|
|
129
|
+
// non-iframe flow - Amber も NIP-46 経由(nostrsigner:// の代わりに nostrconnect:// を使用)
|
|
223
130
|
if (link && !iframeUrl) {
|
|
224
131
|
if (link === 'amber') {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
// Emit for the "Connecting..." spinner
|
|
232
|
-
this.emit('onAuthUrl', { url });
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
const pubkey = await signer.getPublicKey(id);
|
|
236
|
-
const info: Info = {
|
|
237
|
-
pubkey,
|
|
238
|
-
name: nip19.npubEncode(pubkey),
|
|
239
|
-
authMethod: 'amber' as any,
|
|
240
|
-
relays: [],
|
|
241
|
-
signerPubkey: '',
|
|
242
|
-
};
|
|
243
|
-
this.onAuth('login', info);
|
|
244
|
-
return info;
|
|
245
|
-
} catch (e) {
|
|
246
|
-
console.log('Amber getPublicKey failed or was blocked', e);
|
|
247
|
-
// Fallback: wait for onAuth to be called (e.g. via user clicking Continue)
|
|
248
|
-
return new Promise(resolve => {
|
|
249
|
-
const handler = (info: Info | null) => {
|
|
250
|
-
if (info && info.authMethod === ('amber' as any)) {
|
|
251
|
-
this.off('onUserInfo', handler); // Use onUserInfo as a proxy for onAuth
|
|
252
|
-
resolve(info);
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
this.on('onUserInfo', handler);
|
|
256
|
-
});
|
|
257
|
-
}
|
|
132
|
+
// Amber に nostrconnect:// URL を渡す
|
|
133
|
+
const nostrconnectUrl = await this.createNostrConnect(relays);
|
|
134
|
+
console.log('Amber flow via NIP-46, opening:', nostrconnectUrl);
|
|
135
|
+
window.location.href = nostrconnectUrl;
|
|
136
|
+
} else {
|
|
137
|
+
window.open(link, '_blank', 'width=400,height=700');
|
|
258
138
|
}
|
|
259
|
-
window.open(link, '_blank', 'width=400,height=700');
|
|
260
139
|
}
|
|
261
140
|
|
|
262
141
|
// init nip46 signer
|
|
@@ -420,9 +299,12 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
420
299
|
}
|
|
421
300
|
|
|
422
301
|
public async setAmber(info: Info) {
|
|
302
|
+
// Amber now uses NIP-46 (nostrconnect) like other signers
|
|
423
303
|
this.releaseSigner();
|
|
424
|
-
this.
|
|
304
|
+
await this.startAuth();
|
|
305
|
+
await this.initSigner(info);
|
|
425
306
|
this.onAuth('login', info);
|
|
307
|
+
await this.endAuth();
|
|
426
308
|
}
|
|
427
309
|
|
|
428
310
|
public async createAccount(nip05: string) {
|
|
@@ -453,7 +335,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
453
335
|
this.signer = null;
|
|
454
336
|
this.signerErrCallback?.('cancelled');
|
|
455
337
|
this.localSigner = null;
|
|
456
|
-
this.amberSigner = null;
|
|
457
338
|
}
|
|
458
339
|
|
|
459
340
|
public async logout(keepSigner = false) {
|
|
@@ -803,10 +684,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
803
684
|
event.pubkey = getPublicKey(this.localSigner.privateKey!);
|
|
804
685
|
event.id = getEventHash(event);
|
|
805
686
|
event.sig = await this.localSigner.sign(event);
|
|
806
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
807
|
-
const userInfo = this.params.userInfo!;
|
|
808
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
809
|
-
return this.amberSigner.signEvent(event);
|
|
810
687
|
} else {
|
|
811
688
|
event.pubkey = this.signer?.remotePubkey;
|
|
812
689
|
event.id = getEventHash(event);
|
|
@@ -839,10 +716,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
839
716
|
public async encrypt04(pubkey: string, plaintext: string) {
|
|
840
717
|
if (this.localSigner) {
|
|
841
718
|
return this.localSigner.encrypt(pubkey, plaintext);
|
|
842
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
843
|
-
const userInfo = this.params.userInfo!;
|
|
844
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
845
|
-
return this.amberSigner.encrypt04(pubkey, plaintext);
|
|
846
719
|
} else {
|
|
847
720
|
// adapter supports encrypt(pubkey, plaintext)
|
|
848
721
|
if (this.signer && typeof this.signer.encrypt === 'function') {
|
|
@@ -856,10 +729,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
856
729
|
public async decrypt04(pubkey: string, ciphertext: string) {
|
|
857
730
|
if (this.localSigner) {
|
|
858
731
|
return this.localSigner.decrypt(pubkey, ciphertext);
|
|
859
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
860
|
-
const userInfo = this.params.userInfo!;
|
|
861
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
862
|
-
return this.amberSigner.decrypt04(pubkey, ciphertext);
|
|
863
732
|
} else {
|
|
864
733
|
// If signer supports direct decrypt(pubkey, ciphertext), use it
|
|
865
734
|
if (this.signer && typeof this.signer.decrypt === 'function') {
|
|
@@ -874,10 +743,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
874
743
|
public async encrypt44(pubkey: string, plaintext: string) {
|
|
875
744
|
if (this.localSigner) {
|
|
876
745
|
return this.nip44Codec.encrypt(this.localSigner.privateKey!, pubkey, plaintext);
|
|
877
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
878
|
-
const userInfo = this.params.userInfo!;
|
|
879
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
880
|
-
return this.amberSigner.encrypt44(pubkey, plaintext);
|
|
881
746
|
} else {
|
|
882
747
|
// no support of nip44 in legacy signer implementation
|
|
883
748
|
return this.codec_call('nip44_encrypt', pubkey, plaintext);
|
|
@@ -887,10 +752,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
887
752
|
public async decrypt44(pubkey: string, ciphertext: string) {
|
|
888
753
|
if (this.localSigner) {
|
|
889
754
|
return this.nip44Codec.decrypt(this.localSigner.privateKey!, pubkey, ciphertext);
|
|
890
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
891
|
-
const userInfo = this.params.userInfo!;
|
|
892
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
893
|
-
return this.amberSigner.decrypt44(pubkey, ciphertext);
|
|
894
755
|
} else {
|
|
895
756
|
// no support of nip44 in legacy signer implementation
|
|
896
757
|
return this.codec_call('nip44_decrypt', pubkey, ciphertext);
|