@konemono/nostr-login 1.15.7 → 1.16.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konemono/nostr-login",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
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.
|
|
30
|
+
"@konemono/nostr-login-components": "^1.5.0",
|
|
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",
|
|
@@ -456,6 +456,15 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
public async logout(keepSigner = false) {
|
|
459
|
+
// NIP-46 logout を送信(signer が session を削除)
|
|
460
|
+
if (this.signer && !keepSigner) {
|
|
461
|
+
try {
|
|
462
|
+
await this.signer.logout();
|
|
463
|
+
} catch (e) {
|
|
464
|
+
console.warn('NIP-46 logout RPC failed (non-fatal):', e);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
459
468
|
if (!keepSigner) this.releaseSigner();
|
|
460
469
|
|
|
461
470
|
localStorageRemoveCurrentAccount();
|
|
@@ -693,6 +702,16 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
693
702
|
await this.signer!.initUserPubkey(info.pubkey);
|
|
694
703
|
}
|
|
695
704
|
|
|
705
|
+
// NIP-46 Spec: 接続確立後に switch_relays を即時送信
|
|
706
|
+
const newRelays = await this.signer!.switchRelays();
|
|
707
|
+
if (newRelays && newRelays.length > 0) {
|
|
708
|
+
this.pool.removeAllRelays();
|
|
709
|
+
for (const r of newRelays) {
|
|
710
|
+
this.pool.addRelay(r);
|
|
711
|
+
}
|
|
712
|
+
this.signer!.rpc.resubscribe();
|
|
713
|
+
}
|
|
714
|
+
|
|
696
715
|
info.pubkey = this.signer!.userPubkey as string;
|
|
697
716
|
info.signerPubkey = this.signer!.bunkerPubkey;
|
|
698
717
|
|
|
@@ -862,7 +881,7 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
862
881
|
return this.localSigner.decrypt({ pubkey }, ciphertext);
|
|
863
882
|
}
|
|
864
883
|
await this.ensureRelayConnection();
|
|
865
|
-
return this.
|
|
884
|
+
return this.signer!.decrypt(pubkey, ciphertext);
|
|
866
885
|
}
|
|
867
886
|
|
|
868
887
|
public async encrypt44(pubkey: string, plaintext: string) {
|
|
@@ -870,7 +889,7 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
870
889
|
return this.nip44Codec.encrypt(this.localSigner.privateKey!, pubkey, plaintext);
|
|
871
890
|
}
|
|
872
891
|
await this.ensureRelayConnection();
|
|
873
|
-
return this.
|
|
892
|
+
return this.signer!.nip44Encrypt(pubkey, plaintext);
|
|
874
893
|
}
|
|
875
894
|
|
|
876
895
|
public async decrypt44(pubkey: string, ciphertext: string) {
|
|
@@ -878,7 +897,7 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
878
897
|
return this.nip44Codec.decrypt(this.localSigner.privateKey!, pubkey, ciphertext);
|
|
879
898
|
}
|
|
880
899
|
await this.ensureRelayConnection();
|
|
881
|
-
return this.
|
|
900
|
+
return this.signer!.nip44Decrypt(pubkey, ciphertext);
|
|
882
901
|
}
|
|
883
902
|
}
|
|
884
903
|
|
|
@@ -151,7 +151,94 @@ export class Nip46Signer extends EventEmitter {
|
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* NIP-46 ping — signer の死活確認
|
|
156
|
+
*/
|
|
157
|
+
public async ping(): Promise<boolean> {
|
|
158
|
+
return new Promise<boolean>((resolve, reject) => {
|
|
159
|
+
this.rpc.sendRequest(this.bunkerPubkey, 'ping', [], 24133, (response: RpcResponse) => {
|
|
160
|
+
if (response.error) {
|
|
161
|
+
reject(new Nip46Error(response.error, 'TIMEOUT'));
|
|
162
|
+
} else {
|
|
163
|
+
resolve(response.result === 'pong');
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* NIP-46 switch_relays — リレーリストの更新
|
|
171
|
+
* Spec: 接続確立後に client が即時送信、signer が relay リストを返す
|
|
172
|
+
*/
|
|
173
|
+
public async switchRelays(): Promise<string[] | null> {
|
|
174
|
+
return new Promise<string[] | null>((resolve, reject) => {
|
|
175
|
+
this.rpc.sendRequest(this.bunkerPubkey, 'switch_relays', [], 24133, (response: RpcResponse) => {
|
|
176
|
+
if (response.error) {
|
|
177
|
+
reject(new Nip46Error(response.error, 'TIMEOUT'));
|
|
178
|
+
} else {
|
|
179
|
+
// result は JSON 文字列: ["wss://...", ...] または "null"
|
|
180
|
+
try {
|
|
181
|
+
const parsed = JSON.parse(response.result);
|
|
182
|
+
resolve(Array.isArray(parsed) ? parsed : null);
|
|
183
|
+
} catch {
|
|
184
|
+
resolve(null);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* NIP-46 logout — リモート signer にセッション終了を通知
|
|
193
|
+
*/
|
|
194
|
+
public async logout(): Promise<void> {
|
|
195
|
+
return new Promise<void>((resolve, reject) => {
|
|
196
|
+
this.rpc.sendRequest(this.bunkerPubkey, 'logout', [], 24133, (response: RpcResponse) => {
|
|
197
|
+
if (response.error) {
|
|
198
|
+
reject(new Nip46Error(response.error, 'TIMEOUT'));
|
|
199
|
+
} else {
|
|
200
|
+
resolve();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* NIP-46 remote encrypt (NIP-44)
|
|
208
|
+
*/
|
|
209
|
+
public async nip44Encrypt(recipientPubkey: string, plaintext: string): Promise<string> {
|
|
210
|
+
return new Promise<string>((resolve, reject) => {
|
|
211
|
+
this.rpc.sendRequest(this.bunkerPubkey, 'nip44_encrypt', [recipientPubkey, plaintext], 24133, (response: RpcResponse) => {
|
|
212
|
+
if (response.error) {
|
|
213
|
+
reject(new Nip46Error(response.error, 'SIGNER_REJECTED'));
|
|
214
|
+
} else {
|
|
215
|
+
resolve(response.result);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* NIP-46 remote decrypt (NIP-44)
|
|
223
|
+
*/
|
|
224
|
+
public async nip44Decrypt(senderPubkey: string, ciphertext: string): Promise<string> {
|
|
225
|
+
return new Promise<string>((resolve, reject) => {
|
|
226
|
+
this.rpc.sendRequest(this.bunkerPubkey, 'nip44_decrypt', [senderPubkey, ciphertext], 24133, (response: RpcResponse) => {
|
|
227
|
+
if (response.error) {
|
|
228
|
+
reject(new Nip46Error(response.error, 'SIGNER_REJECTED'));
|
|
229
|
+
} else {
|
|
230
|
+
resolve(response.result);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @deprecated NIP-46 spec から create_account は別 NIP へ移動済み。
|
|
238
|
+
* 将来的に削除されます。
|
|
239
|
+
*/
|
|
154
240
|
public async createAccount2({ bunkerPubkey, name, domain, perms = '' }: { bunkerPubkey: string; name: string; domain: string; perms?: string }) {
|
|
241
|
+
console.warn('[DEPRECATED] createAccount2 is deprecated per NIP-46 spec. Will be removed in a future version.');
|
|
155
242
|
const params = [name, domain, '', perms];
|
|
156
243
|
|
|
157
244
|
const r = await new Promise<RpcResponse>((ok, err) => {
|