@konemono/nostr-login 1.9.5 → 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 -149
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,96 +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.onAuth('login', info);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// URLクリーンアップをより徹底的に
|
|
149
|
-
const url = new URL(window.location.href);
|
|
150
|
-
let changed = false;
|
|
151
|
-
if (url.searchParams.has('event')) {
|
|
152
|
-
url.searchParams.delete('event');
|
|
153
|
-
changed = true;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// パス末尾が結果と一致する場合はパスもクリア
|
|
157
|
-
const pathParts = url.pathname.split('/');
|
|
158
|
-
if (pathParts.length > 0 && pathParts[pathParts.length - 1] === response.result) {
|
|
159
|
-
pathParts.pop();
|
|
160
|
-
url.pathname = pathParts.join('/') || '/';
|
|
161
|
-
changed = true;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (changed) {
|
|
165
|
-
console.log('Cleaning up Amber response URL', url.toString());
|
|
166
|
-
window.history.replaceState({}, '', url.toString());
|
|
167
|
-
}
|
|
168
76
|
}
|
|
169
77
|
|
|
170
78
|
public isIframe() {
|
|
@@ -218,44 +126,15 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
218
126
|
|
|
219
127
|
console.log('nostrconnect info', info, link);
|
|
220
128
|
|
|
221
|
-
// non-iframe flow
|
|
129
|
+
// non-iframe flow - Amber も NIP-46 経由(nostrsigner:// の代わりに nostrconnect:// を使用)
|
|
222
130
|
if (link && !iframeUrl) {
|
|
223
131
|
if (link === 'amber') {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// Emit for the "Connecting..." spinner
|
|
231
|
-
this.emit('onAuthUrl', { url });
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
const pubkey = await signer.getPublicKey(id);
|
|
235
|
-
const info: Info = {
|
|
236
|
-
pubkey,
|
|
237
|
-
name: nip19.npubEncode(pubkey),
|
|
238
|
-
authMethod: 'amber' as any,
|
|
239
|
-
relays: [],
|
|
240
|
-
signerPubkey: '',
|
|
241
|
-
};
|
|
242
|
-
this.onAuth('login', info);
|
|
243
|
-
return info;
|
|
244
|
-
} catch (e) {
|
|
245
|
-
console.log('Amber getPublicKey failed or was blocked', e);
|
|
246
|
-
// Fallback: wait for onAuth to be called (e.g. via user clicking Continue)
|
|
247
|
-
return new Promise(resolve => {
|
|
248
|
-
const handler = (info: Info | null) => {
|
|
249
|
-
if (info && info.authMethod === ('amber' as any)) {
|
|
250
|
-
this.off('onUserInfo', handler); // Use onUserInfo as a proxy for onAuth
|
|
251
|
-
resolve(info);
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
this.on('onUserInfo', handler);
|
|
255
|
-
});
|
|
256
|
-
}
|
|
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');
|
|
257
137
|
}
|
|
258
|
-
window.open(link, '_blank', 'width=400,height=700');
|
|
259
138
|
}
|
|
260
139
|
|
|
261
140
|
// init nip46 signer
|
|
@@ -419,9 +298,12 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
419
298
|
}
|
|
420
299
|
|
|
421
300
|
public async setAmber(info: Info) {
|
|
301
|
+
// Amber now uses NIP-46 (nostrconnect) like other signers
|
|
422
302
|
this.releaseSigner();
|
|
423
|
-
this.
|
|
303
|
+
await this.startAuth();
|
|
304
|
+
await this.initSigner(info);
|
|
424
305
|
this.onAuth('login', info);
|
|
306
|
+
await this.endAuth();
|
|
425
307
|
}
|
|
426
308
|
|
|
427
309
|
public async createAccount(nip05: string) {
|
|
@@ -452,7 +334,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
452
334
|
this.signer = null;
|
|
453
335
|
this.signerErrCallback?.('cancelled');
|
|
454
336
|
this.localSigner = null;
|
|
455
|
-
this.amberSigner = null;
|
|
456
337
|
}
|
|
457
338
|
|
|
458
339
|
public async logout(keepSigner = false) {
|
|
@@ -802,10 +683,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
802
683
|
event.pubkey = getPublicKey(this.localSigner.privateKey!);
|
|
803
684
|
event.id = getEventHash(event);
|
|
804
685
|
event.sig = await this.localSigner.sign(event);
|
|
805
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
806
|
-
const userInfo = this.params.userInfo!;
|
|
807
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
808
|
-
return this.amberSigner.signEvent(event);
|
|
809
686
|
} else {
|
|
810
687
|
event.pubkey = this.signer?.remotePubkey;
|
|
811
688
|
event.id = getEventHash(event);
|
|
@@ -838,10 +715,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
838
715
|
public async encrypt04(pubkey: string, plaintext: string) {
|
|
839
716
|
if (this.localSigner) {
|
|
840
717
|
return this.localSigner.encrypt(pubkey, plaintext);
|
|
841
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
842
|
-
const userInfo = this.params.userInfo!;
|
|
843
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
844
|
-
return this.amberSigner.encrypt04(pubkey, plaintext);
|
|
845
718
|
} else {
|
|
846
719
|
// adapter supports encrypt(pubkey, plaintext)
|
|
847
720
|
if (this.signer && typeof this.signer.encrypt === 'function') {
|
|
@@ -855,10 +728,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
855
728
|
public async decrypt04(pubkey: string, ciphertext: string) {
|
|
856
729
|
if (this.localSigner) {
|
|
857
730
|
return this.localSigner.decrypt(pubkey, ciphertext);
|
|
858
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
859
|
-
const userInfo = this.params.userInfo!;
|
|
860
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
861
|
-
return this.amberSigner.decrypt04(pubkey, ciphertext);
|
|
862
731
|
} else {
|
|
863
732
|
// If signer supports direct decrypt(pubkey, ciphertext), use it
|
|
864
733
|
if (this.signer && typeof this.signer.decrypt === 'function') {
|
|
@@ -873,10 +742,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
873
742
|
public async encrypt44(pubkey: string, plaintext: string) {
|
|
874
743
|
if (this.localSigner) {
|
|
875
744
|
return this.nip44Codec.encrypt(this.localSigner.privateKey!, pubkey, plaintext);
|
|
876
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
877
|
-
const userInfo = this.params.userInfo!;
|
|
878
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
879
|
-
return this.amberSigner.encrypt44(pubkey, plaintext);
|
|
880
745
|
} else {
|
|
881
746
|
// no support of nip44 in legacy signer implementation
|
|
882
747
|
return this.codec_call('nip44_encrypt', pubkey, plaintext);
|
|
@@ -886,10 +751,6 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
886
751
|
public async decrypt44(pubkey: string, ciphertext: string) {
|
|
887
752
|
if (this.localSigner) {
|
|
888
753
|
return this.nip44Codec.decrypt(this.localSigner.privateKey!, pubkey, ciphertext);
|
|
889
|
-
} else if (this.params.userInfo?.authMethod === ('amber' as any)) {
|
|
890
|
-
const userInfo = this.params.userInfo!;
|
|
891
|
-
if (!this.amberSigner) this.amberSigner = new AmberDirectSigner(userInfo.pubkey);
|
|
892
|
-
return this.amberSigner.decrypt44(pubkey, ciphertext);
|
|
893
754
|
} else {
|
|
894
755
|
// no support of nip44 in legacy signer implementation
|
|
895
756
|
return this.codec_call('nip44_decrypt', pubkey, ciphertext);
|