@bzzsocial/ndk 3.0.3-bzz.7 → 3.0.3-bzz.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.d.mts CHANGED
@@ -879,6 +879,8 @@ declare class NDKRelayConnectivity {
879
879
  baseEoseTimeout: number;
880
880
  /** The latest NIP-42 challenge on the current connection. */
881
881
  authChallenge?: string;
882
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
883
+ authedAs?: string;
882
884
  private authInFlight?;
883
885
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
884
886
  authTimeoutMs: number;
@@ -985,6 +987,7 @@ declare class NDKRelayConnectivity {
985
987
  */
986
988
  authenticate(reason?: NDKAuthReason): Promise<boolean>;
987
989
  private runAuth;
990
+ private attemptAuth;
988
991
  private signAuthEvent;
989
992
  private withAuthTimeout;
990
993
  /**
@@ -1316,6 +1319,7 @@ interface NDKRelayConnectionStats {
1316
1319
  * @emits NDKRelay#eose when the relay has reached the end of stored events
1317
1320
  * @emits NDKRelay#auth when the relay requires authentication
1318
1321
  * @emits NDKRelay#authed when the relay has authenticated
1322
+ * @emits NDKRelay#auth:settled when an AUTH attempt ends, whichever way (true: signed in)
1319
1323
  * @emits NDKRelay#delayed-connect when the relay will wait before reconnecting
1320
1324
  */
1321
1325
  declare class NDKRelay extends EventEmitter<{
@@ -1330,6 +1334,7 @@ declare class NDKRelay extends EventEmitter<{
1330
1334
  auth: (challenge: string) => void;
1331
1335
  authed: () => void;
1332
1336
  "auth:failed": (error: Error) => void;
1337
+ "auth:settled": (authed: boolean) => void;
1333
1338
  published: (event: NDKEvent) => void;
1334
1339
  "publish:failed": (event: NDKEvent, error: Error) => void;
1335
1340
  "delayed-connect": (delayInMs: number) => void;
@@ -1385,6 +1390,11 @@ declare class NDKRelay extends EventEmitter<{
1385
1390
  * The NIP-42 challenge the relay sent on the current connection, if any.
1386
1391
  */
1387
1392
  get authChallenge(): string | undefined;
1393
+ /**
1394
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
1395
+ * connection closes: a new one signs in afresh.
1396
+ */
1397
+ get authedAs(): string | undefined;
1388
1398
  /**
1389
1399
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
1390
1400
  * NDK default). Resolves true once the relay accepts, false otherwise.
package/dist/index.d.ts CHANGED
@@ -879,6 +879,8 @@ declare class NDKRelayConnectivity {
879
879
  baseEoseTimeout: number;
880
880
  /** The latest NIP-42 challenge on the current connection. */
881
881
  authChallenge?: string;
882
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
883
+ authedAs?: string;
882
884
  private authInFlight?;
883
885
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
884
886
  authTimeoutMs: number;
@@ -985,6 +987,7 @@ declare class NDKRelayConnectivity {
985
987
  */
986
988
  authenticate(reason?: NDKAuthReason): Promise<boolean>;
987
989
  private runAuth;
990
+ private attemptAuth;
988
991
  private signAuthEvent;
989
992
  private withAuthTimeout;
990
993
  /**
@@ -1316,6 +1319,7 @@ interface NDKRelayConnectionStats {
1316
1319
  * @emits NDKRelay#eose when the relay has reached the end of stored events
1317
1320
  * @emits NDKRelay#auth when the relay requires authentication
1318
1321
  * @emits NDKRelay#authed when the relay has authenticated
1322
+ * @emits NDKRelay#auth:settled when an AUTH attempt ends, whichever way (true: signed in)
1319
1323
  * @emits NDKRelay#delayed-connect when the relay will wait before reconnecting
1320
1324
  */
1321
1325
  declare class NDKRelay extends EventEmitter<{
@@ -1330,6 +1334,7 @@ declare class NDKRelay extends EventEmitter<{
1330
1334
  auth: (challenge: string) => void;
1331
1335
  authed: () => void;
1332
1336
  "auth:failed": (error: Error) => void;
1337
+ "auth:settled": (authed: boolean) => void;
1333
1338
  published: (event: NDKEvent) => void;
1334
1339
  "publish:failed": (event: NDKEvent, error: Error) => void;
1335
1340
  "delayed-connect": (delayInMs: number) => void;
@@ -1385,6 +1390,11 @@ declare class NDKRelay extends EventEmitter<{
1385
1390
  * The NIP-42 challenge the relay sent on the current connection, if any.
1386
1391
  */
1387
1392
  get authChallenge(): string | undefined;
1393
+ /**
1394
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
1395
+ * connection closes: a new one signs in afresh.
1396
+ */
1397
+ get authedAs(): string | undefined;
1388
1398
  /**
1389
1399
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
1390
1400
  * NDK default). Resolves true once the relay accepts, false otherwise.
package/dist/index.js CHANGED
@@ -831,6 +831,7 @@ var NDKRelayKeepalive = class {
831
831
  this.onSilenceDetected = onSilenceDetected;
832
832
  this.timeout = timeout;
833
833
  }
834
+ onSilenceDetected;
834
835
  lastActivity = Date.now();
835
836
  timer;
836
837
  timeout;
@@ -914,6 +915,8 @@ var NDKRelayConnectivity = class {
914
915
  baseEoseTimeout = 4400;
915
916
  /** The latest NIP-42 challenge on the current connection. */
916
917
  authChallenge;
918
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
919
+ authedAs;
917
920
  authInFlight;
918
921
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
919
922
  authTimeoutMs = 1e4;
@@ -1138,6 +1141,7 @@ var NDKRelayConnectivity = class {
1138
1141
  this.updateConnectionStats.connected();
1139
1142
  this._status = 5 /* CONNECTED */;
1140
1143
  this.authChallenge = void 0;
1144
+ this.authedAs = void 0;
1141
1145
  this.authWanted = void 0;
1142
1146
  if (!this.wsStateMonitor) this.setupMonitoring();
1143
1147
  this.keepalive?.start();
@@ -1166,6 +1170,7 @@ var NDKRelayConnectivity = class {
1166
1170
  }
1167
1171
  this._status = 1 /* DISCONNECTED */;
1168
1172
  this.authChallenge = void 0;
1173
+ this.authedAs = void 0;
1169
1174
  this.authWanted = void 0;
1170
1175
  this.ndkRelay.emit("disconnect");
1171
1176
  }
@@ -1333,6 +1338,11 @@ var NDKRelayConnectivity = class {
1333
1338
  return attempt;
1334
1339
  }
1335
1340
  async runAuth(authPolicy, challenge, reason) {
1341
+ const authed = await this.attemptAuth(authPolicy, challenge, reason);
1342
+ this.ndkRelay.emit("auth:settled", authed);
1343
+ return authed;
1344
+ }
1345
+ async attemptAuth(authPolicy, challenge, reason) {
1336
1346
  this._status = 7 /* AUTHENTICATING */;
1337
1347
  try {
1338
1348
  let res = await authPolicy(this.ndkRelay, challenge, reason);
@@ -1346,6 +1356,7 @@ var NDKRelayConnectivity = class {
1346
1356
  await this.withAuthTimeout(this.auth(res));
1347
1357
  if (this.authChallenge !== challenge || !this.connected) return false;
1348
1358
  this._status = 8 /* AUTHENTICATED */;
1359
+ this.authedAs = res.pubkey;
1349
1360
  this.debug("Authentication successful");
1350
1361
  this.ndkRelay.emit("authed");
1351
1362
  this.retryPendingAuthPublishes();
@@ -2572,6 +2583,13 @@ var NDKRelay = class _NDKRelay extends import_tseep.EventEmitter {
2572
2583
  get authChallenge() {
2573
2584
  return this.connectivity.authChallenge;
2574
2585
  }
2586
+ /**
2587
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
2588
+ * connection closes: a new one signs in afresh.
2589
+ */
2590
+ get authedAs() {
2591
+ return this.connectivity.authedAs;
2592
+ }
2575
2593
  /**
2576
2594
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
2577
2595
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -3728,13 +3746,13 @@ function signatureVerificationInit(w) {
3728
3746
  msg.data,
3729
3747
  "\n\n\u{1F50D} This likely means:",
3730
3748
  "\n 1. You have a STALE worker.js file that needs updating",
3731
- "\n 2. Version mismatch between @nostr-dev-kit/ndk and deployed worker",
3749
+ "\n 2. Version mismatch between @bzzsocial/ndk and deployed worker",
3732
3750
  "\n 3. Wrong worker is being used for signature verification",
3733
3751
  "\n\n\u2705 Solution: Update your worker files:",
3734
- "\n cp node_modules/@nostr-dev-kit/ndk/dist/workers/sig-verification.js public/",
3752
+ "\n cp node_modules/@bzzsocial/ndk/dist/workers/sig-verification.js public/",
3735
3753
  "\n cp node_modules/@nostr-dev-kit/cache-sqlite-wasm/dist/worker.js public/",
3736
3754
  "\n\n\u{1F4A1} Or use Vite/bundler imports instead of static files:",
3737
- '\n import SigWorker from "@nostr-dev-kit/ndk/workers/sig-verification?worker"'
3755
+ '\n import SigWorker from "@bzzsocial/ndk/workers/sig-verification?worker"'
3738
3756
  );
3739
3757
  return;
3740
3758
  }
@@ -9444,7 +9462,7 @@ No events can match this time range!`,
9444
9462
  guards.error(
9445
9463
  GuardrailCheckId.FILTER_BECH32_IN_ARRAY,
9446
9464
  `Filter[${filterIndex}].ids[${idx}] contains bech32: "${id}". IDs must be hex, not bech32.`,
9447
- `Use filterFromId() to decode bech32 first: import { filterFromId } from "@nostr-dev-kit/ndk"`,
9465
+ `Use filterFromId() to decode bech32 first: import { filterFromId } from "@bzzsocial/ndk"`,
9448
9466
  false
9449
9467
  // Fatal error - cannot be disabled
9450
9468
  );
package/dist/index.mjs CHANGED
@@ -652,6 +652,7 @@ var NDKRelayKeepalive = class {
652
652
  this.onSilenceDetected = onSilenceDetected;
653
653
  this.timeout = timeout;
654
654
  }
655
+ onSilenceDetected;
655
656
  lastActivity = Date.now();
656
657
  timer;
657
658
  timeout;
@@ -735,6 +736,8 @@ var NDKRelayConnectivity = class {
735
736
  baseEoseTimeout = 4400;
736
737
  /** The latest NIP-42 challenge on the current connection. */
737
738
  authChallenge;
739
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
740
+ authedAs;
738
741
  authInFlight;
739
742
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
740
743
  authTimeoutMs = 1e4;
@@ -959,6 +962,7 @@ var NDKRelayConnectivity = class {
959
962
  this.updateConnectionStats.connected();
960
963
  this._status = 5 /* CONNECTED */;
961
964
  this.authChallenge = void 0;
965
+ this.authedAs = void 0;
962
966
  this.authWanted = void 0;
963
967
  if (!this.wsStateMonitor) this.setupMonitoring();
964
968
  this.keepalive?.start();
@@ -987,6 +991,7 @@ var NDKRelayConnectivity = class {
987
991
  }
988
992
  this._status = 1 /* DISCONNECTED */;
989
993
  this.authChallenge = void 0;
994
+ this.authedAs = void 0;
990
995
  this.authWanted = void 0;
991
996
  this.ndkRelay.emit("disconnect");
992
997
  }
@@ -1154,6 +1159,11 @@ var NDKRelayConnectivity = class {
1154
1159
  return attempt;
1155
1160
  }
1156
1161
  async runAuth(authPolicy, challenge, reason) {
1162
+ const authed = await this.attemptAuth(authPolicy, challenge, reason);
1163
+ this.ndkRelay.emit("auth:settled", authed);
1164
+ return authed;
1165
+ }
1166
+ async attemptAuth(authPolicy, challenge, reason) {
1157
1167
  this._status = 7 /* AUTHENTICATING */;
1158
1168
  try {
1159
1169
  let res = await authPolicy(this.ndkRelay, challenge, reason);
@@ -1167,6 +1177,7 @@ var NDKRelayConnectivity = class {
1167
1177
  await this.withAuthTimeout(this.auth(res));
1168
1178
  if (this.authChallenge !== challenge || !this.connected) return false;
1169
1179
  this._status = 8 /* AUTHENTICATED */;
1180
+ this.authedAs = res.pubkey;
1170
1181
  this.debug("Authentication successful");
1171
1182
  this.ndkRelay.emit("authed");
1172
1183
  this.retryPendingAuthPublishes();
@@ -2393,6 +2404,13 @@ var NDKRelay = class _NDKRelay extends EventEmitter {
2393
2404
  get authChallenge() {
2394
2405
  return this.connectivity.authChallenge;
2395
2406
  }
2407
+ /**
2408
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
2409
+ * connection closes: a new one signs in afresh.
2410
+ */
2411
+ get authedAs() {
2412
+ return this.connectivity.authedAs;
2413
+ }
2396
2414
  /**
2397
2415
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
2398
2416
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -3549,13 +3567,13 @@ function signatureVerificationInit(w) {
3549
3567
  msg.data,
3550
3568
  "\n\n\u{1F50D} This likely means:",
3551
3569
  "\n 1. You have a STALE worker.js file that needs updating",
3552
- "\n 2. Version mismatch between @nostr-dev-kit/ndk and deployed worker",
3570
+ "\n 2. Version mismatch between @bzzsocial/ndk and deployed worker",
3553
3571
  "\n 3. Wrong worker is being used for signature verification",
3554
3572
  "\n\n\u2705 Solution: Update your worker files:",
3555
- "\n cp node_modules/@nostr-dev-kit/ndk/dist/workers/sig-verification.js public/",
3573
+ "\n cp node_modules/@bzzsocial/ndk/dist/workers/sig-verification.js public/",
3556
3574
  "\n cp node_modules/@nostr-dev-kit/cache-sqlite-wasm/dist/worker.js public/",
3557
3575
  "\n\n\u{1F4A1} Or use Vite/bundler imports instead of static files:",
3558
- '\n import SigWorker from "@nostr-dev-kit/ndk/workers/sig-verification?worker"'
3576
+ '\n import SigWorker from "@bzzsocial/ndk/workers/sig-verification?worker"'
3559
3577
  );
3560
3578
  return;
3561
3579
  }
@@ -9265,7 +9283,7 @@ No events can match this time range!`,
9265
9283
  guards.error(
9266
9284
  GuardrailCheckId.FILTER_BECH32_IN_ARRAY,
9267
9285
  `Filter[${filterIndex}].ids[${idx}] contains bech32: "${id}". IDs must be hex, not bech32.`,
9268
- `Use filterFromId() to decode bech32 first: import { filterFromId } from "@nostr-dev-kit/ndk"`,
9286
+ `Use filterFromId() to decode bech32 first: import { filterFromId } from "@bzzsocial/ndk"`,
9269
9287
  false
9270
9288
  // Fatal error - cannot be disabled
9271
9289
  );
@@ -778,6 +778,8 @@ declare class NDKRelayConnectivity {
778
778
  baseEoseTimeout: number;
779
779
  /** The latest NIP-42 challenge on the current connection. */
780
780
  authChallenge?: string;
781
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
782
+ authedAs?: string;
781
783
  private authInFlight?;
782
784
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
783
785
  authTimeoutMs: number;
@@ -884,6 +886,7 @@ declare class NDKRelayConnectivity {
884
886
  */
885
887
  authenticate(reason?: NDKAuthReason): Promise<boolean>;
886
888
  private runAuth;
889
+ private attemptAuth;
887
890
  private signAuthEvent;
888
891
  private withAuthTimeout;
889
892
  /**
@@ -1163,6 +1166,7 @@ interface NDKRelayConnectionStats {
1163
1166
  * @emits NDKRelay#eose when the relay has reached the end of stored events
1164
1167
  * @emits NDKRelay#auth when the relay requires authentication
1165
1168
  * @emits NDKRelay#authed when the relay has authenticated
1169
+ * @emits NDKRelay#auth:settled when an AUTH attempt ends, whichever way (true: signed in)
1166
1170
  * @emits NDKRelay#delayed-connect when the relay will wait before reconnecting
1167
1171
  */
1168
1172
  declare class NDKRelay extends EventEmitter<{
@@ -1177,6 +1181,7 @@ declare class NDKRelay extends EventEmitter<{
1177
1181
  auth: (challenge: string) => void;
1178
1182
  authed: () => void;
1179
1183
  "auth:failed": (error: Error) => void;
1184
+ "auth:settled": (authed: boolean) => void;
1180
1185
  published: (event: NDKEvent) => void;
1181
1186
  "publish:failed": (event: NDKEvent, error: Error) => void;
1182
1187
  "delayed-connect": (delayInMs: number) => void;
@@ -1232,6 +1237,11 @@ declare class NDKRelay extends EventEmitter<{
1232
1237
  * The NIP-42 challenge the relay sent on the current connection, if any.
1233
1238
  */
1234
1239
  get authChallenge(): string | undefined;
1240
+ /**
1241
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
1242
+ * connection closes: a new one signs in afresh.
1243
+ */
1244
+ get authedAs(): string | undefined;
1235
1245
  /**
1236
1246
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
1237
1247
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -4244,7 +4254,7 @@ declare class TestFixture {
4244
4254
  * @example
4245
4255
  * ```typescript
4246
4256
  * import { vi } from 'vitest';
4247
- * import { TimeController } from '@nostr-dev-kit/ndk/test';
4257
+ * import { TimeController } from '@bzzsocial/ndk/test';
4248
4258
  *
4249
4259
  * beforeEach(() => {
4250
4260
  * vi.useFakeTimers();
@@ -4301,7 +4311,7 @@ declare class TimeController {
4301
4311
  * @example
4302
4312
  * ```typescript
4303
4313
  * import { vi } from 'vitest';
4304
- * import { withTimeControl } from '@nostr-dev-kit/ndk/test';
4314
+ * import { withTimeControl } from '@bzzsocial/ndk/test';
4305
4315
  *
4306
4316
  * const timeController = withTimeControl(vi);
4307
4317
  *
@@ -4325,7 +4335,7 @@ declare function withTimeControl(viObject: any): (fn: (timeController: typeof Ti
4325
4335
  *
4326
4336
  * @example
4327
4337
  * ```typescript
4328
- * import { EventGenerator, UserGenerator } from '@nostr-dev-kit/ndk/test';
4338
+ * import { EventGenerator, UserGenerator } from '@bzzsocial/ndk/test';
4329
4339
  *
4330
4340
  * // Initialize once in your test setup
4331
4341
  * EventGenerator.setNDK(ndk);
@@ -4375,7 +4385,7 @@ type Proof = {
4375
4385
  *
4376
4386
  * @example
4377
4387
  * ```typescript
4378
- * import { mockNutzap, UserGenerator } from '@nostr-dev-kit/ndk/test';
4388
+ * import { mockNutzap, UserGenerator } from '@bzzsocial/ndk/test';
4379
4389
  *
4380
4390
  * const alice = await UserGenerator.getUser('alice', ndk);
4381
4391
  * const bob = await UserGenerator.getUser('bob', ndk);
@@ -4416,7 +4426,7 @@ declare function mockNutzap(mint: string, amount: number, ndk: any, { senderPk,
4416
4426
  *
4417
4427
  * @example
4418
4428
  * ```typescript
4419
- * import { mockProof } from '@nostr-dev-kit/ndk/test';
4429
+ * import { mockProof } from '@bzzsocial/ndk/test';
4420
4430
  *
4421
4431
  * // Create a simple proof
4422
4432
  * const proof = mockProof('https://mint.example.com', 100);
@@ -4451,7 +4461,7 @@ interface RelayMockOptions {
4451
4461
  *
4452
4462
  * @example
4453
4463
  * ```typescript
4454
- * import { RelayMock } from '@nostr-dev-kit/ndk/test';
4464
+ * import { RelayMock } from '@bzzsocial/ndk/test';
4455
4465
  *
4456
4466
  * // Create a mock relay
4457
4467
  * const relay = new RelayMock('wss://relay.example.com', {
@@ -4528,7 +4538,7 @@ declare class RelayMock extends EventEmitter$1 {
4528
4538
  *
4529
4539
  * @example
4530
4540
  * ```typescript
4531
- * import { RelayPoolMock, EventGenerator, UserGenerator } from '@nostr-dev-kit/ndk/test';
4541
+ * import { RelayPoolMock, EventGenerator, UserGenerator } from '@bzzsocial/ndk/test';
4532
4542
  *
4533
4543
  * const pool = new RelayPoolMock();
4534
4544
  * const ndk = new NDK({ explicitRelayUrls: [] });
@@ -778,6 +778,8 @@ declare class NDKRelayConnectivity {
778
778
  baseEoseTimeout: number;
779
779
  /** The latest NIP-42 challenge on the current connection. */
780
780
  authChallenge?: string;
781
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
782
+ authedAs?: string;
781
783
  private authInFlight?;
782
784
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
783
785
  authTimeoutMs: number;
@@ -884,6 +886,7 @@ declare class NDKRelayConnectivity {
884
886
  */
885
887
  authenticate(reason?: NDKAuthReason): Promise<boolean>;
886
888
  private runAuth;
889
+ private attemptAuth;
887
890
  private signAuthEvent;
888
891
  private withAuthTimeout;
889
892
  /**
@@ -1163,6 +1166,7 @@ interface NDKRelayConnectionStats {
1163
1166
  * @emits NDKRelay#eose when the relay has reached the end of stored events
1164
1167
  * @emits NDKRelay#auth when the relay requires authentication
1165
1168
  * @emits NDKRelay#authed when the relay has authenticated
1169
+ * @emits NDKRelay#auth:settled when an AUTH attempt ends, whichever way (true: signed in)
1166
1170
  * @emits NDKRelay#delayed-connect when the relay will wait before reconnecting
1167
1171
  */
1168
1172
  declare class NDKRelay extends EventEmitter<{
@@ -1177,6 +1181,7 @@ declare class NDKRelay extends EventEmitter<{
1177
1181
  auth: (challenge: string) => void;
1178
1182
  authed: () => void;
1179
1183
  "auth:failed": (error: Error) => void;
1184
+ "auth:settled": (authed: boolean) => void;
1180
1185
  published: (event: NDKEvent) => void;
1181
1186
  "publish:failed": (event: NDKEvent, error: Error) => void;
1182
1187
  "delayed-connect": (delayInMs: number) => void;
@@ -1232,6 +1237,11 @@ declare class NDKRelay extends EventEmitter<{
1232
1237
  * The NIP-42 challenge the relay sent on the current connection, if any.
1233
1238
  */
1234
1239
  get authChallenge(): string | undefined;
1240
+ /**
1241
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
1242
+ * connection closes: a new one signs in afresh.
1243
+ */
1244
+ get authedAs(): string | undefined;
1235
1245
  /**
1236
1246
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
1237
1247
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -4244,7 +4254,7 @@ declare class TestFixture {
4244
4254
  * @example
4245
4255
  * ```typescript
4246
4256
  * import { vi } from 'vitest';
4247
- * import { TimeController } from '@nostr-dev-kit/ndk/test';
4257
+ * import { TimeController } from '@bzzsocial/ndk/test';
4248
4258
  *
4249
4259
  * beforeEach(() => {
4250
4260
  * vi.useFakeTimers();
@@ -4301,7 +4311,7 @@ declare class TimeController {
4301
4311
  * @example
4302
4312
  * ```typescript
4303
4313
  * import { vi } from 'vitest';
4304
- * import { withTimeControl } from '@nostr-dev-kit/ndk/test';
4314
+ * import { withTimeControl } from '@bzzsocial/ndk/test';
4305
4315
  *
4306
4316
  * const timeController = withTimeControl(vi);
4307
4317
  *
@@ -4325,7 +4335,7 @@ declare function withTimeControl(viObject: any): (fn: (timeController: typeof Ti
4325
4335
  *
4326
4336
  * @example
4327
4337
  * ```typescript
4328
- * import { EventGenerator, UserGenerator } from '@nostr-dev-kit/ndk/test';
4338
+ * import { EventGenerator, UserGenerator } from '@bzzsocial/ndk/test';
4329
4339
  *
4330
4340
  * // Initialize once in your test setup
4331
4341
  * EventGenerator.setNDK(ndk);
@@ -4375,7 +4385,7 @@ type Proof = {
4375
4385
  *
4376
4386
  * @example
4377
4387
  * ```typescript
4378
- * import { mockNutzap, UserGenerator } from '@nostr-dev-kit/ndk/test';
4388
+ * import { mockNutzap, UserGenerator } from '@bzzsocial/ndk/test';
4379
4389
  *
4380
4390
  * const alice = await UserGenerator.getUser('alice', ndk);
4381
4391
  * const bob = await UserGenerator.getUser('bob', ndk);
@@ -4416,7 +4426,7 @@ declare function mockNutzap(mint: string, amount: number, ndk: any, { senderPk,
4416
4426
  *
4417
4427
  * @example
4418
4428
  * ```typescript
4419
- * import { mockProof } from '@nostr-dev-kit/ndk/test';
4429
+ * import { mockProof } from '@bzzsocial/ndk/test';
4420
4430
  *
4421
4431
  * // Create a simple proof
4422
4432
  * const proof = mockProof('https://mint.example.com', 100);
@@ -4451,7 +4461,7 @@ interface RelayMockOptions {
4451
4461
  *
4452
4462
  * @example
4453
4463
  * ```typescript
4454
- * import { RelayMock } from '@nostr-dev-kit/ndk/test';
4464
+ * import { RelayMock } from '@bzzsocial/ndk/test';
4455
4465
  *
4456
4466
  * // Create a mock relay
4457
4467
  * const relay = new RelayMock('wss://relay.example.com', {
@@ -4528,7 +4538,7 @@ declare class RelayMock extends EventEmitter$1 {
4528
4538
  *
4529
4539
  * @example
4530
4540
  * ```typescript
4531
- * import { RelayPoolMock, EventGenerator, UserGenerator } from '@nostr-dev-kit/ndk/test';
4541
+ * import { RelayPoolMock, EventGenerator, UserGenerator } from '@bzzsocial/ndk/test';
4532
4542
  *
4533
4543
  * const pool = new RelayPoolMock();
4534
4544
  * const ndk = new NDK({ explicitRelayUrls: [] });
@@ -1138,6 +1138,7 @@ var NDKRelayKeepalive = class {
1138
1138
  this.onSilenceDetected = onSilenceDetected;
1139
1139
  this.timeout = timeout;
1140
1140
  }
1141
+ onSilenceDetected;
1141
1142
  lastActivity = Date.now();
1142
1143
  timer;
1143
1144
  timeout;
@@ -1221,6 +1222,8 @@ var NDKRelayConnectivity = class {
1221
1222
  baseEoseTimeout = 4400;
1222
1223
  /** The latest NIP-42 challenge on the current connection. */
1223
1224
  authChallenge;
1225
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
1226
+ authedAs;
1224
1227
  authInFlight;
1225
1228
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
1226
1229
  authTimeoutMs = 1e4;
@@ -1445,6 +1448,7 @@ var NDKRelayConnectivity = class {
1445
1448
  this.updateConnectionStats.connected();
1446
1449
  this._status = 5 /* CONNECTED */;
1447
1450
  this.authChallenge = void 0;
1451
+ this.authedAs = void 0;
1448
1452
  this.authWanted = void 0;
1449
1453
  if (!this.wsStateMonitor) this.setupMonitoring();
1450
1454
  this.keepalive?.start();
@@ -1473,6 +1477,7 @@ var NDKRelayConnectivity = class {
1473
1477
  }
1474
1478
  this._status = 1 /* DISCONNECTED */;
1475
1479
  this.authChallenge = void 0;
1480
+ this.authedAs = void 0;
1476
1481
  this.authWanted = void 0;
1477
1482
  this.ndkRelay.emit("disconnect");
1478
1483
  }
@@ -1640,6 +1645,11 @@ var NDKRelayConnectivity = class {
1640
1645
  return attempt;
1641
1646
  }
1642
1647
  async runAuth(authPolicy, challenge, reason) {
1648
+ const authed = await this.attemptAuth(authPolicy, challenge, reason);
1649
+ this.ndkRelay.emit("auth:settled", authed);
1650
+ return authed;
1651
+ }
1652
+ async attemptAuth(authPolicy, challenge, reason) {
1643
1653
  this._status = 7 /* AUTHENTICATING */;
1644
1654
  try {
1645
1655
  let res = await authPolicy(this.ndkRelay, challenge, reason);
@@ -1653,6 +1663,7 @@ var NDKRelayConnectivity = class {
1653
1663
  await this.withAuthTimeout(this.auth(res));
1654
1664
  if (this.authChallenge !== challenge || !this.connected) return false;
1655
1665
  this._status = 8 /* AUTHENTICATED */;
1666
+ this.authedAs = res.pubkey;
1656
1667
  this.debug("Authentication successful");
1657
1668
  this.ndkRelay.emit("authed");
1658
1669
  this.retryPendingAuthPublishes();
@@ -2757,6 +2768,13 @@ var NDKRelay = class _NDKRelay extends import_tseep.EventEmitter {
2757
2768
  get authChallenge() {
2758
2769
  return this.connectivity.authChallenge;
2759
2770
  }
2771
+ /**
2772
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
2773
+ * connection closes: a new one signs in afresh.
2774
+ */
2775
+ get authedAs() {
2776
+ return this.connectivity.authedAs;
2777
+ }
2760
2778
  /**
2761
2779
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
2762
2780
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -3817,13 +3835,13 @@ function signatureVerificationInit(w) {
3817
3835
  msg.data,
3818
3836
  "\n\n\u{1F50D} This likely means:",
3819
3837
  "\n 1. You have a STALE worker.js file that needs updating",
3820
- "\n 2. Version mismatch between @nostr-dev-kit/ndk and deployed worker",
3838
+ "\n 2. Version mismatch between @bzzsocial/ndk and deployed worker",
3821
3839
  "\n 3. Wrong worker is being used for signature verification",
3822
3840
  "\n\n\u2705 Solution: Update your worker files:",
3823
- "\n cp node_modules/@nostr-dev-kit/ndk/dist/workers/sig-verification.js public/",
3841
+ "\n cp node_modules/@bzzsocial/ndk/dist/workers/sig-verification.js public/",
3824
3842
  "\n cp node_modules/@nostr-dev-kit/cache-sqlite-wasm/dist/worker.js public/",
3825
3843
  "\n\n\u{1F4A1} Or use Vite/bundler imports instead of static files:",
3826
- '\n import SigWorker from "@nostr-dev-kit/ndk/workers/sig-verification?worker"'
3844
+ '\n import SigWorker from "@bzzsocial/ndk/workers/sig-verification?worker"'
3827
3845
  );
3828
3846
  return;
3829
3847
  }
@@ -10812,7 +10830,7 @@ No events can match this time range!`,
10812
10830
  guards.error(
10813
10831
  GuardrailCheckId.FILTER_BECH32_IN_ARRAY,
10814
10832
  `Filter[${filterIndex}].ids[${idx}] contains bech32: "${id}". IDs must be hex, not bech32.`,
10815
- `Use filterFromId() to decode bech32 first: import { filterFromId } from "@nostr-dev-kit/ndk"`,
10833
+ `Use filterFromId() to decode bech32 first: import { filterFromId } from "@bzzsocial/ndk"`,
10816
10834
  false
10817
10835
  // Fatal error - cannot be disabled
10818
10836
  );
@@ -1105,6 +1105,7 @@ var NDKRelayKeepalive = class {
1105
1105
  this.onSilenceDetected = onSilenceDetected;
1106
1106
  this.timeout = timeout;
1107
1107
  }
1108
+ onSilenceDetected;
1108
1109
  lastActivity = Date.now();
1109
1110
  timer;
1110
1111
  timeout;
@@ -1188,6 +1189,8 @@ var NDKRelayConnectivity = class {
1188
1189
  baseEoseTimeout = 4400;
1189
1190
  /** The latest NIP-42 challenge on the current connection. */
1190
1191
  authChallenge;
1192
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
1193
+ authedAs;
1191
1194
  authInFlight;
1192
1195
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
1193
1196
  authTimeoutMs = 1e4;
@@ -1412,6 +1415,7 @@ var NDKRelayConnectivity = class {
1412
1415
  this.updateConnectionStats.connected();
1413
1416
  this._status = 5 /* CONNECTED */;
1414
1417
  this.authChallenge = void 0;
1418
+ this.authedAs = void 0;
1415
1419
  this.authWanted = void 0;
1416
1420
  if (!this.wsStateMonitor) this.setupMonitoring();
1417
1421
  this.keepalive?.start();
@@ -1440,6 +1444,7 @@ var NDKRelayConnectivity = class {
1440
1444
  }
1441
1445
  this._status = 1 /* DISCONNECTED */;
1442
1446
  this.authChallenge = void 0;
1447
+ this.authedAs = void 0;
1443
1448
  this.authWanted = void 0;
1444
1449
  this.ndkRelay.emit("disconnect");
1445
1450
  }
@@ -1607,6 +1612,11 @@ var NDKRelayConnectivity = class {
1607
1612
  return attempt;
1608
1613
  }
1609
1614
  async runAuth(authPolicy, challenge, reason) {
1615
+ const authed = await this.attemptAuth(authPolicy, challenge, reason);
1616
+ this.ndkRelay.emit("auth:settled", authed);
1617
+ return authed;
1618
+ }
1619
+ async attemptAuth(authPolicy, challenge, reason) {
1610
1620
  this._status = 7 /* AUTHENTICATING */;
1611
1621
  try {
1612
1622
  let res = await authPolicy(this.ndkRelay, challenge, reason);
@@ -1620,6 +1630,7 @@ var NDKRelayConnectivity = class {
1620
1630
  await this.withAuthTimeout(this.auth(res));
1621
1631
  if (this.authChallenge !== challenge || !this.connected) return false;
1622
1632
  this._status = 8 /* AUTHENTICATED */;
1633
+ this.authedAs = res.pubkey;
1623
1634
  this.debug("Authentication successful");
1624
1635
  this.ndkRelay.emit("authed");
1625
1636
  this.retryPendingAuthPublishes();
@@ -2724,6 +2735,13 @@ var NDKRelay = class _NDKRelay extends EventEmitter {
2724
2735
  get authChallenge() {
2725
2736
  return this.connectivity.authChallenge;
2726
2737
  }
2738
+ /**
2739
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
2740
+ * connection closes: a new one signs in afresh.
2741
+ */
2742
+ get authedAs() {
2743
+ return this.connectivity.authedAs;
2744
+ }
2727
2745
  /**
2728
2746
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
2729
2747
  * NDK default). Resolves true once the relay accepts, false otherwise.
@@ -3784,13 +3802,13 @@ function signatureVerificationInit(w) {
3784
3802
  msg.data,
3785
3803
  "\n\n\u{1F50D} This likely means:",
3786
3804
  "\n 1. You have a STALE worker.js file that needs updating",
3787
- "\n 2. Version mismatch between @nostr-dev-kit/ndk and deployed worker",
3805
+ "\n 2. Version mismatch between @bzzsocial/ndk and deployed worker",
3788
3806
  "\n 3. Wrong worker is being used for signature verification",
3789
3807
  "\n\n\u2705 Solution: Update your worker files:",
3790
- "\n cp node_modules/@nostr-dev-kit/ndk/dist/workers/sig-verification.js public/",
3808
+ "\n cp node_modules/@bzzsocial/ndk/dist/workers/sig-verification.js public/",
3791
3809
  "\n cp node_modules/@nostr-dev-kit/cache-sqlite-wasm/dist/worker.js public/",
3792
3810
  "\n\n\u{1F4A1} Or use Vite/bundler imports instead of static files:",
3793
- '\n import SigWorker from "@nostr-dev-kit/ndk/workers/sig-verification?worker"'
3811
+ '\n import SigWorker from "@bzzsocial/ndk/workers/sig-verification?worker"'
3794
3812
  );
3795
3813
  return;
3796
3814
  }
@@ -10781,7 +10799,7 @@ No events can match this time range!`,
10781
10799
  guards.error(
10782
10800
  GuardrailCheckId.FILTER_BECH32_IN_ARRAY,
10783
10801
  `Filter[${filterIndex}].ids[${idx}] contains bech32: "${id}". IDs must be hex, not bech32.`,
10784
- `Use filterFromId() to decode bech32 first: import { filterFromId } from "@nostr-dev-kit/ndk"`,
10802
+ `Use filterFromId() to decode bech32 first: import { filterFromId } from "@bzzsocial/ndk"`,
10785
10803
  false
10786
10804
  // Fatal error - cannot be disabled
10787
10805
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bzzsocial/ndk",
3
- "version": "3.0.3-bzz.7",
3
+ "version": "3.0.3-bzz.8",
4
4
  "description": "NDK - Nostr Development Kit. Includes AI Guardrails to catch common mistakes during development.",
5
5
  "homepage": "https://github.com/bzzsocial/ndk/tree/bzz/core#readme",
6
6
  "repository": {
@@ -194,4 +194,31 @@ describe("AUTH on demand", () => {
194
194
  await vi.waitFor(() => expect(failed).toHaveBeenCalled());
195
195
  expect(relay.status).toBe(NDKRelayStatus.CONNECTED);
196
196
  });
197
+
198
+ it("settles every attempt, a quietly declined offer included", async () => {
199
+ const { policy } = onDemandPolicy();
200
+ const r = connectedRelay(policy);
201
+ const settled = vi.fn();
202
+ r.relay.on("auth:settled", settled);
203
+
204
+ r.recv(["AUTH", "c1"]);
205
+ await tick();
206
+ expect(settled.mock.lastCall?.[0]).toBe(false);
207
+
208
+ const authed = r.relay.authenticate("manual");
209
+ await acceptAuth(r);
210
+ await expect(authed).resolves.toBe(true);
211
+ expect(settled.mock.lastCall?.[0]).toBe(true);
212
+ expect(settled).toHaveBeenCalledTimes(2);
213
+ });
214
+
215
+ it("records whom the connection signed in as, until it closes", async () => {
216
+ const r = connectedRelay(async () => true);
217
+ r.recv(["AUTH", "c1"]);
218
+ await acceptAuth(r);
219
+ expect(r.relay.authedAs).toBe((await r.ndk.signer!.user()).pubkey);
220
+
221
+ (r.relay.connectivity as any).onDisconnect();
222
+ expect(r.relay.authedAs).toBeUndefined();
223
+ });
197
224
  });
@@ -58,6 +58,8 @@ export class NDKRelayConnectivity {
58
58
 
59
59
  /** The latest NIP-42 challenge on the current connection. */
60
60
  public authChallenge?: string;
61
+ /** The pubkey this connection is signed in as (NIP-42), until the connection closes. */
62
+ public authedAs?: string;
61
63
  private authInFlight?: Promise<boolean>;
62
64
  /** How long to wait for the relay's OK on an AUTH event, and for a signer to sign it. */
63
65
  public authTimeoutMs = 10_000;
@@ -329,6 +331,7 @@ export class NDKRelayConnectivity {
329
331
  this.updateConnectionStats.connected();
330
332
  this._status = NDKRelayStatus.CONNECTED;
331
333
  this.authChallenge = undefined;
334
+ this.authedAs = undefined;
332
335
  this.authWanted = undefined;
333
336
 
334
337
  // disconnect() stops monitoring; a new connection needs it again
@@ -370,6 +373,7 @@ export class NDKRelayConnectivity {
370
373
  }
371
374
  this._status = NDKRelayStatus.DISCONNECTED;
372
375
  this.authChallenge = undefined;
376
+ this.authedAs = undefined;
373
377
  this.authWanted = undefined;
374
378
  this.ndkRelay.emit("disconnect");
375
379
  }
@@ -609,6 +613,18 @@ export class NDKRelayConnectivity {
609
613
  authPolicy: NonNullable<NDKRelay["authPolicy"]>,
610
614
  challenge: string,
611
615
  reason: NDKAuthReason,
616
+ ): Promise<boolean> {
617
+ const authed = await this.attemptAuth(authPolicy, challenge, reason);
618
+ // Every attempt ends here, however it ended (a quietly declined offer and a connection
619
+ // that changed underneath included), for whoever waits on the outcome.
620
+ this.ndkRelay.emit("auth:settled", authed);
621
+ return authed;
622
+ }
623
+
624
+ private async attemptAuth(
625
+ authPolicy: NonNullable<NDKRelay["authPolicy"]>,
626
+ challenge: string,
627
+ reason: NDKAuthReason,
612
628
  ): Promise<boolean> {
613
629
  this._status = NDKRelayStatus.AUTHENTICATING;
614
630
 
@@ -631,6 +647,7 @@ export class NDKRelayConnectivity {
631
647
  if (this.authChallenge !== challenge || !this.connected) return false;
632
648
 
633
649
  this._status = NDKRelayStatus.AUTHENTICATED;
650
+ this.authedAs = res.pubkey;
634
651
  this.debug("Authentication successful");
635
652
  this.ndkRelay.emit("authed");
636
653
  this.retryPendingAuthPublishes();
@@ -85,6 +85,7 @@ export interface NDKRelayConnectionStats {
85
85
  * @emits NDKRelay#eose when the relay has reached the end of stored events
86
86
  * @emits NDKRelay#auth when the relay requires authentication
87
87
  * @emits NDKRelay#authed when the relay has authenticated
88
+ * @emits NDKRelay#auth:settled when an AUTH attempt ends, whichever way (true: signed in)
88
89
  * @emits NDKRelay#delayed-connect when the relay will wait before reconnecting
89
90
  */
90
91
  export class NDKRelay extends EventEmitter<{
@@ -100,6 +101,7 @@ export class NDKRelay extends EventEmitter<{
100
101
  auth: (challenge: string) => void;
101
102
  authed: () => void;
102
103
  "auth:failed": (error: Error) => void;
104
+ "auth:settled": (authed: boolean) => void;
103
105
  published: (event: NDKEvent) => void;
104
106
  "publish:failed": (event: NDKEvent, error: Error) => void;
105
107
  "delayed-connect": (delayInMs: number) => void;
@@ -228,6 +230,14 @@ export class NDKRelay extends EventEmitter<{
228
230
  return this.connectivity.authChallenge;
229
231
  }
230
232
 
233
+ /**
234
+ * The pubkey the current connection is signed in as (NIP-42), if it is. Cleared when the
235
+ * connection closes: a new one signs in afresh.
236
+ */
237
+ get authedAs(): string | undefined {
238
+ return this.connectivity.authedAs;
239
+ }
240
+
231
241
  /**
232
242
  * Answers the relay's NIP-42 challenge with this relay's auth policy (or the
233
243
  * NDK default). Resolves true once the relay accepts, false otherwise.