@unicitylabs/sphere-sdk 0.6.3 → 0.6.4

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.
@@ -1,3 +1,4 @@
1
+ import { NostrKeyManager, Event } from '@unicitylabs/nostr-js-sdk';
1
2
  import { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient';
2
3
  import { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient';
3
4
  import { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/bft/RootTrustBase';
@@ -656,6 +657,12 @@ declare class NostrTransportProvider implements TransportProvider {
656
657
  */
657
658
  private stripContentPrefix;
658
659
  private ensureConnected;
660
+ /**
661
+ * Async version of ensureConnected — reconnects if the original transport
662
+ * lost its WebSocket while subscriptions are suppressed (mux handles events).
663
+ * Used by resolve methods which are always async.
664
+ */
665
+ private ensureConnectedForResolve;
659
666
  private ensureReady;
660
667
  private emitEvent;
661
668
  /**
@@ -664,6 +671,11 @@ declare class NostrTransportProvider implements TransportProvider {
664
671
  * because NIP17.createGiftWrap hardcodes kind 14 for the inner rumor.
665
672
  */
666
673
  private createCustomKindGiftWrap;
674
+ /**
675
+ * Create a NIP-17 gift wrap with a custom rumor kind.
676
+ * Shared between NostrTransportProvider and MultiAddressTransportMux.
677
+ */
678
+ static createCustomKindGiftWrap(keyManager: NostrKeyManager, recipientPubkeyHex: string, content: string, rumorKind: number): Event;
667
679
  }
668
680
 
669
681
  /**
@@ -1,3 +1,4 @@
1
+ import { NostrKeyManager, Event } from '@unicitylabs/nostr-js-sdk';
1
2
  import { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient';
2
3
  import { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient';
3
4
  import { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/bft/RootTrustBase';
@@ -656,6 +657,12 @@ declare class NostrTransportProvider implements TransportProvider {
656
657
  */
657
658
  private stripContentPrefix;
658
659
  private ensureConnected;
660
+ /**
661
+ * Async version of ensureConnected — reconnects if the original transport
662
+ * lost its WebSocket while subscriptions are suppressed (mux handles events).
663
+ * Used by resolve methods which are always async.
664
+ */
665
+ private ensureConnectedForResolve;
659
666
  private ensureReady;
660
667
  private emitEvent;
661
668
  /**
@@ -664,6 +671,11 @@ declare class NostrTransportProvider implements TransportProvider {
664
671
  * because NIP17.createGiftWrap hardcodes kind 14 for the inner rumor.
665
672
  */
666
673
  private createCustomKindGiftWrap;
674
+ /**
675
+ * Create a NIP-17 gift wrap with a custom rumor kind.
676
+ * Shared between NostrTransportProvider and MultiAddressTransportMux.
677
+ */
678
+ static createCustomKindGiftWrap(keyManager: NostrKeyManager, recipientPubkeyHex: string, content: string, rumorKind: number): Event;
667
679
  }
668
680
 
669
681
  /**
@@ -1078,7 +1078,7 @@ function defaultUUIDGenerator() {
1078
1078
  var COMPOSING_INDICATOR_KIND = 25050;
1079
1079
  var TIMESTAMP_RANDOMIZATION = 2 * 24 * 60 * 60;
1080
1080
  var EVENT_KINDS = NOSTR_EVENT_KINDS;
1081
- var NostrTransportProvider = class {
1081
+ var NostrTransportProvider = class _NostrTransportProvider {
1082
1082
  id = "nostr";
1083
1083
  name = "Nostr Transport";
1084
1084
  type = "p2p";
@@ -1609,11 +1609,11 @@ var NostrTransportProvider = class {
1609
1609
  return this.resolveNametagInfo(identifier);
1610
1610
  }
1611
1611
  async resolveNametag(nametag) {
1612
- this.ensureConnected();
1612
+ await this.ensureConnectedForResolve();
1613
1613
  return this.nostrClient.queryPubkeyByNametag(nametag);
1614
1614
  }
1615
1615
  async resolveNametagInfo(nametag) {
1616
- this.ensureConnected();
1616
+ await this.ensureConnectedForResolve();
1617
1617
  const binding = await this.nostrClient.queryBindingByNametag(nametag);
1618
1618
  if (!binding) {
1619
1619
  logger.debug("Nostr", `resolveNametagInfo: no binding events found for Unicity ID "${nametag}"`);
@@ -1626,7 +1626,7 @@ var NostrTransportProvider = class {
1626
1626
  * Performs reverse lookup via nostr-js-sdk with first-seen-wins anti-hijacking.
1627
1627
  */
1628
1628
  async resolveAddressInfo(address) {
1629
- this.ensureConnected();
1629
+ await this.ensureConnectedForResolve();
1630
1630
  const binding = await this.nostrClient.queryBindingByAddress(address);
1631
1631
  if (!binding) return null;
1632
1632
  return this.bindingInfoToPeerInfo(binding);
@@ -1661,7 +1661,7 @@ var NostrTransportProvider = class {
1661
1661
  * Queries binding events authored by the given pubkey.
1662
1662
  */
1663
1663
  async resolveTransportPubkeyInfo(transportPubkey) {
1664
- this.ensureConnected();
1664
+ await this.ensureConnectedForResolve();
1665
1665
  const events = await this.queryEvents({
1666
1666
  kinds: [EVENT_KINDS.NAMETAG_BINDING],
1667
1667
  authors: [transportPubkey],
@@ -1696,7 +1696,7 @@ var NostrTransportProvider = class {
1696
1696
  * Used for HD address discovery — single relay query with multi-author filter.
1697
1697
  */
1698
1698
  async discoverAddresses(transportPubkeys) {
1699
- this.ensureConnected();
1699
+ await this.ensureConnectedForResolve();
1700
1700
  if (transportPubkeys.length === 0) return [];
1701
1701
  const events = await this.queryEvents({
1702
1702
  kinds: [EVENT_KINDS.NAMETAG_BINDING],
@@ -1735,7 +1735,10 @@ var NostrTransportProvider = class {
1735
1735
  * @returns Decrypted nametag or null if none found
1736
1736
  */
1737
1737
  async recoverNametag() {
1738
- this.ensureReady();
1738
+ await this.ensureConnectedForResolve();
1739
+ if (!this.identity) {
1740
+ throw new SphereError("Identity not set", "NOT_INITIALIZED");
1741
+ }
1739
1742
  if (!this.identity || !this.keyManager) {
1740
1743
  throw new SphereError("Identity not set", "NOT_INITIALIZED");
1741
1744
  }
@@ -2471,6 +2474,31 @@ var NostrTransportProvider = class {
2471
2474
  throw new SphereError("NostrTransportProvider not connected", "TRANSPORT_ERROR");
2472
2475
  }
2473
2476
  }
2477
+ /**
2478
+ * Async version of ensureConnected — reconnects if the original transport
2479
+ * lost its WebSocket while subscriptions are suppressed (mux handles events).
2480
+ * Used by resolve methods which are always async.
2481
+ */
2482
+ async ensureConnectedForResolve() {
2483
+ if (this.isConnected()) return;
2484
+ if (this._subscriptionsSuppressed && this.nostrClient) {
2485
+ logger.debug("Nostr", "Suppressed transport disconnected \u2014 reconnecting for resolve");
2486
+ try {
2487
+ await Promise.race([
2488
+ this.nostrClient.connect(...this.config.relays),
2489
+ new Promise(
2490
+ (_, reject) => setTimeout(() => reject(new Error("reconnect timeout")), 5e3)
2491
+ )
2492
+ ]);
2493
+ if (this.nostrClient.isConnected()) {
2494
+ this.status = "connected";
2495
+ return;
2496
+ }
2497
+ } catch {
2498
+ }
2499
+ }
2500
+ throw new SphereError("NostrTransportProvider not connected", "TRANSPORT_ERROR");
2501
+ }
2474
2502
  ensureReady() {
2475
2503
  this.ensureConnected();
2476
2504
  if (!this.identity) {
@@ -2492,16 +2520,23 @@ var NostrTransportProvider = class {
2492
2520
  * because NIP17.createGiftWrap hardcodes kind 14 for the inner rumor.
2493
2521
  */
2494
2522
  createCustomKindGiftWrap(recipientPubkeyHex, content, rumorKind) {
2495
- const senderPubkey = this.keyManager.getPublicKeyHex();
2523
+ return _NostrTransportProvider.createCustomKindGiftWrap(this.keyManager, recipientPubkeyHex, content, rumorKind);
2524
+ }
2525
+ /**
2526
+ * Create a NIP-17 gift wrap with a custom rumor kind.
2527
+ * Shared between NostrTransportProvider and MultiAddressTransportMux.
2528
+ */
2529
+ static createCustomKindGiftWrap(keyManager, recipientPubkeyHex, content, rumorKind) {
2530
+ const senderPubkey = keyManager.getPublicKeyHex();
2496
2531
  const now = Math.floor(Date.now() / 1e3);
2497
2532
  const rumorTags = [["p", recipientPubkeyHex]];
2498
2533
  const rumorSerialized = JSON.stringify([0, senderPubkey, now, rumorKind, rumorTags, content]);
2499
2534
  const rumorId = bytesToHex(sha256(new TextEncoder().encode(rumorSerialized)));
2500
2535
  const rumor = { id: rumorId, pubkey: senderPubkey, created_at: now, kind: rumorKind, tags: rumorTags, content };
2501
2536
  const recipientPubkeyBytes = hexToBytes(recipientPubkeyHex);
2502
- const encryptedRumor = NIP44.encrypt(JSON.stringify(rumor), this.keyManager.getPrivateKey(), recipientPubkeyBytes);
2537
+ const encryptedRumor = NIP44.encrypt(JSON.stringify(rumor), keyManager.getPrivateKey(), recipientPubkeyBytes);
2503
2538
  const sealTimestamp = now + Math.floor(Math.random() * 2 * TIMESTAMP_RANDOMIZATION) - TIMESTAMP_RANDOMIZATION;
2504
- const seal = NostrEventClass.create(this.keyManager, {
2539
+ const seal = NostrEventClass.create(keyManager, {
2505
2540
  kind: EventKinds.SEAL,
2506
2541
  tags: [],
2507
2542
  content: encryptedRumor,