@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.15.7",
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.4.7",
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.codec_call('nip04_decrypt', pubkey, ciphertext);
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.codec_call('nip44_encrypt', pubkey, plaintext);
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.codec_call('nip44_decrypt', pubkey, ciphertext);
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) => {