@konemono/nostr-login 1.9.6 → 1.9.7
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 +10 -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,15 @@ 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 フローとして扱う
|
|
133
|
+
// popup は開かない - Amber は自動で nostrconnect:// を処理する
|
|
134
|
+
console.log('Amber flow via NIP-46 (nostrconnect)');
|
|
135
|
+
} else {
|
|
136
|
+
window.open(link, '_blank', 'width=400,height=700');
|
|
258
137
|
}
|
|
259
|
-
window.open(link, '_blank', 'width=400,height=700');
|
|
260
138
|
}
|
|
261
139
|
|
|
262
140
|
// init nip46 signer
|
|
@@ -420,9 +298,12 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
420
298
|
}
|
|
421
299
|
|
|
422
300
|
public async setAmber(info: Info) {
|
|
301
|
+
// Amber now uses NIP-46 (nostrconnect) like other signers
|
|
423
302
|
this.releaseSigner();
|
|
424
|
-
this.
|
|
303
|
+
await this.startAuth();
|
|
304
|
+
await this.initSigner(info);
|
|
425
305
|
this.onAuth('login', info);
|
|
306
|
+
await this.endAuth();
|
|
426
307
|
}
|
|
427
308
|
|
|
428
309
|
public async createAccount(nip05: string) {
|
|
@@ -453,7 +334,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
453
334
|
this.signer = null;
|
|
454
335
|
this.signerErrCallback?.('cancelled');
|
|
455
336
|
this.localSigner = null;
|
|
456
|
-
this.amberSigner = null;
|
|
457
337
|
}
|
|
458
338
|
|
|
459
339
|
public async logout(keepSigner = false) {
|
|
@@ -803,10 +683,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
803
683
|
event.pubkey = getPublicKey(this.localSigner.privateKey!);
|
|
804
684
|
event.id = getEventHash(event);
|
|
805
685
|
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
686
|
} else {
|
|
811
687
|
event.pubkey = this.signer?.remotePubkey;
|
|
812
688
|
event.id = getEventHash(event);
|
|
@@ -839,10 +715,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
839
715
|
public async encrypt04(pubkey: string, plaintext: string) {
|
|
840
716
|
if (this.localSigner) {
|
|
841
717
|
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
718
|
} else {
|
|
847
719
|
// adapter supports encrypt(pubkey, plaintext)
|
|
848
720
|
if (this.signer && typeof this.signer.encrypt === 'function') {
|
|
@@ -856,10 +728,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
856
728
|
public async decrypt04(pubkey: string, ciphertext: string) {
|
|
857
729
|
if (this.localSigner) {
|
|
858
730
|
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
731
|
} else {
|
|
864
732
|
// If signer supports direct decrypt(pubkey, ciphertext), use it
|
|
865
733
|
if (this.signer && typeof this.signer.decrypt === 'function') {
|
|
@@ -874,10 +742,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
874
742
|
public async encrypt44(pubkey: string, plaintext: string) {
|
|
875
743
|
if (this.localSigner) {
|
|
876
744
|
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
745
|
} else {
|
|
882
746
|
// no support of nip44 in legacy signer implementation
|
|
883
747
|
return this.codec_call('nip44_encrypt', pubkey, plaintext);
|
|
@@ -887,10 +751,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
887
751
|
public async decrypt44(pubkey: string, ciphertext: string) {
|
|
888
752
|
if (this.localSigner) {
|
|
889
753
|
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
754
|
} else {
|
|
895
755
|
// no support of nip44 in legacy signer implementation
|
|
896
756
|
return this.codec_call('nip44_decrypt', pubkey, ciphertext);
|