@unicitylabs/sphere-sdk 0.5.4 → 0.5.5

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.
Files changed (39) hide show
  1. package/dist/connect/index.cjs +128 -22
  2. package/dist/connect/index.cjs.map +1 -1
  3. package/dist/connect/index.js +128 -22
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/core/index.cjs +670 -473
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +123 -2
  8. package/dist/core/index.d.ts +123 -2
  9. package/dist/core/index.js +667 -473
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/impl/browser/index.cjs +306 -193
  12. package/dist/impl/browser/index.cjs.map +1 -1
  13. package/dist/impl/browser/index.js +306 -193
  14. package/dist/impl/browser/index.js.map +1 -1
  15. package/dist/impl/browser/ipfs.cjs +134 -19
  16. package/dist/impl/browser/ipfs.cjs.map +1 -1
  17. package/dist/impl/browser/ipfs.js +134 -19
  18. package/dist/impl/browser/ipfs.js.map +1 -1
  19. package/dist/impl/nodejs/connect/index.cjs +101 -6
  20. package/dist/impl/nodejs/connect/index.cjs.map +1 -1
  21. package/dist/impl/nodejs/connect/index.js +101 -6
  22. package/dist/impl/nodejs/connect/index.js.map +1 -1
  23. package/dist/impl/nodejs/index.cjs +267 -152
  24. package/dist/impl/nodejs/index.cjs.map +1 -1
  25. package/dist/impl/nodejs/index.d.cts +2 -1
  26. package/dist/impl/nodejs/index.d.ts +2 -1
  27. package/dist/impl/nodejs/index.js +267 -152
  28. package/dist/impl/nodejs/index.js.map +1 -1
  29. package/dist/index.cjs +682 -493
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +124 -8
  32. package/dist/index.d.ts +124 -8
  33. package/dist/index.js +680 -493
  34. package/dist/index.js.map +1 -1
  35. package/dist/l1/index.cjs +139 -32
  36. package/dist/l1/index.cjs.map +1 -1
  37. package/dist/l1/index.js +139 -32
  38. package/dist/l1/index.js.map +1 -1
  39. package/package.json +1 -1
@@ -42,6 +42,110 @@ __export(connect_exports, {
42
42
  });
43
43
  module.exports = __toCommonJS(connect_exports);
44
44
 
45
+ // core/logger.ts
46
+ var LOGGER_KEY = "__sphere_sdk_logger__";
47
+ function getState() {
48
+ const g = globalThis;
49
+ if (!g[LOGGER_KEY]) {
50
+ g[LOGGER_KEY] = { debug: false, tags: {}, handler: null };
51
+ }
52
+ return g[LOGGER_KEY];
53
+ }
54
+ function isEnabled(tag) {
55
+ const state = getState();
56
+ if (tag in state.tags) return state.tags[tag];
57
+ return state.debug;
58
+ }
59
+ var logger = {
60
+ /**
61
+ * Configure the logger. Can be called multiple times (last write wins).
62
+ * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().
63
+ */
64
+ configure(config) {
65
+ const state = getState();
66
+ if (config.debug !== void 0) state.debug = config.debug;
67
+ if (config.handler !== void 0) state.handler = config.handler;
68
+ },
69
+ /**
70
+ * Enable/disable debug logging for a specific tag.
71
+ * Per-tag setting overrides the global debug flag.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * logger.setTagDebug('Nostr', true); // enable only Nostr logs
76
+ * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true
77
+ * ```
78
+ */
79
+ setTagDebug(tag, enabled) {
80
+ getState().tags[tag] = enabled;
81
+ },
82
+ /**
83
+ * Clear per-tag override, falling back to global debug flag.
84
+ */
85
+ clearTagDebug(tag) {
86
+ delete getState().tags[tag];
87
+ },
88
+ /** Returns true if debug mode is enabled for the given tag (or globally). */
89
+ isDebugEnabled(tag) {
90
+ if (tag) return isEnabled(tag);
91
+ return getState().debug;
92
+ },
93
+ /**
94
+ * Debug-level log. Only shown when debug is enabled (globally or for this tag).
95
+ * Use for detailed operational information.
96
+ */
97
+ debug(tag, message, ...args) {
98
+ if (!isEnabled(tag)) return;
99
+ const state = getState();
100
+ if (state.handler) {
101
+ state.handler("debug", tag, message, ...args);
102
+ } else {
103
+ console.log(`[${tag}]`, message, ...args);
104
+ }
105
+ },
106
+ /**
107
+ * Warning-level log. ALWAYS shown regardless of debug flag.
108
+ * Use for important but non-critical issues (timeouts, retries, degraded state).
109
+ */
110
+ warn(tag, message, ...args) {
111
+ const state = getState();
112
+ if (state.handler) {
113
+ state.handler("warn", tag, message, ...args);
114
+ } else {
115
+ console.warn(`[${tag}]`, message, ...args);
116
+ }
117
+ },
118
+ /**
119
+ * Error-level log. ALWAYS shown regardless of debug flag.
120
+ * Use for critical failures that should never be silenced.
121
+ */
122
+ error(tag, message, ...args) {
123
+ const state = getState();
124
+ if (state.handler) {
125
+ state.handler("error", tag, message, ...args);
126
+ } else {
127
+ console.error(`[${tag}]`, message, ...args);
128
+ }
129
+ },
130
+ /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */
131
+ reset() {
132
+ const g = globalThis;
133
+ delete g[LOGGER_KEY];
134
+ }
135
+ };
136
+
137
+ // core/errors.ts
138
+ var SphereError = class extends Error {
139
+ code;
140
+ cause;
141
+ constructor(message, code, cause) {
142
+ super(message);
143
+ this.name = "SphereError";
144
+ this.code = code;
145
+ this.cause = cause;
146
+ }
147
+ };
148
+
45
149
  // constants.ts
46
150
  var STORAGE_KEYS_GLOBAL = {
47
151
  /** Encrypted BIP39 mnemonic */
@@ -306,7 +410,7 @@ var ConnectHost = class {
306
410
  return;
307
411
  }
308
412
  } catch (error) {
309
- console.warn("[ConnectHost] Error handling message:", error);
413
+ logger.warn("ConnectHost", "Error handling message:", error);
310
414
  }
311
415
  }
312
416
  // ===========================================================================
@@ -381,7 +485,7 @@ var ConnectHost = class {
381
485
  this.revokeSession();
382
486
  this.sendResult(msg.id, { disconnected: true });
383
487
  if (disconnectedSession && this.config.onDisconnect) {
384
- Promise.resolve(this.config.onDisconnect(disconnectedSession)).catch(console.warn);
488
+ Promise.resolve(this.config.onDisconnect(disconnectedSession)).catch((err) => logger.warn("Connect", "onDisconnect handler error", err));
385
489
  }
386
490
  return;
387
491
  }
@@ -453,17 +557,17 @@ var ConnectHost = class {
453
557
  return this.sphere.payments.getHistory();
454
558
  case RPC_METHODS.L1_GET_BALANCE:
455
559
  if (!this.sphere.payments.l1) {
456
- throw new Error("L1 module not available");
560
+ throw new SphereError("L1 module not available", "MODULE_NOT_AVAILABLE");
457
561
  }
458
562
  return this.sphere.payments.l1.getBalance();
459
563
  case RPC_METHODS.L1_GET_HISTORY:
460
564
  if (!this.sphere.payments.l1) {
461
- throw new Error("L1 module not available");
565
+ throw new SphereError("L1 module not available", "MODULE_NOT_AVAILABLE");
462
566
  }
463
567
  return this.sphere.payments.l1.getHistory(params.limit);
464
568
  case RPC_METHODS.RESOLVE:
465
569
  if (!params.identifier) {
466
- throw new Error("Missing required parameter: identifier");
570
+ throw new SphereError("Missing required parameter: identifier", "VALIDATION_ERROR");
467
571
  }
468
572
  return this.sphere.resolve(params.identifier);
469
573
  case RPC_METHODS.SUBSCRIBE:
@@ -471,7 +575,7 @@ var ConnectHost = class {
471
575
  case RPC_METHODS.UNSUBSCRIBE:
472
576
  return this.handleUnsubscribe(params.event);
473
577
  case RPC_METHODS.GET_CONVERSATIONS: {
474
- if (!this.sphere.communications) throw new Error("Communications module not available");
578
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
475
579
  const convos = this.sphere.communications.getConversations();
476
580
  const result = [];
477
581
  const needsResolve = [];
@@ -494,7 +598,10 @@ var ConnectHost = class {
494
598
  if (needsResolve.length > 0) {
495
599
  const resolved = await Promise.all(
496
600
  needsResolve.map(
497
- ({ peerPubkey }) => this.sphere.communications.resolvePeerNametag(peerPubkey).catch(() => void 0)
601
+ ({ peerPubkey }) => this.sphere.communications.resolvePeerNametag(peerPubkey).catch((err) => {
602
+ logger.debug("Connect", "Peer nametag resolution failed", err);
603
+ return void 0;
604
+ })
498
605
  )
499
606
  );
500
607
  for (let i = 0; i < needsResolve.length; i++) {
@@ -507,8 +614,8 @@ var ConnectHost = class {
507
614
  return result;
508
615
  }
509
616
  case RPC_METHODS.GET_MESSAGES: {
510
- if (!this.sphere.communications) throw new Error("Communications module not available");
511
- if (!params.peerPubkey) throw new Error("Missing required parameter: peerPubkey");
617
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
618
+ if (!params.peerPubkey) throw new SphereError("Missing required parameter: peerPubkey", "VALIDATION_ERROR");
512
619
  return this.sphere.communications.getConversationPage(
513
620
  params.peerPubkey,
514
621
  {
@@ -518,7 +625,7 @@ var ConnectHost = class {
518
625
  );
519
626
  }
520
627
  case RPC_METHODS.GET_DM_UNREAD_COUNT: {
521
- if (!this.sphere.communications) throw new Error("Communications module not available");
628
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
522
629
  return {
523
630
  unreadCount: this.sphere.communications.getUnreadCount(
524
631
  params.peerPubkey
@@ -526,22 +633,22 @@ var ConnectHost = class {
526
633
  };
527
634
  }
528
635
  case RPC_METHODS.MARK_AS_READ: {
529
- if (!this.sphere.communications) throw new Error("Communications module not available");
636
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
530
637
  if (!params.messageIds || !Array.isArray(params.messageIds)) {
531
- throw new Error("Missing required parameter: messageIds (string[])");
638
+ throw new SphereError("Missing required parameter: messageIds (string[])", "VALIDATION_ERROR");
532
639
  }
533
640
  await this.sphere.communications.markAsRead(params.messageIds);
534
641
  return { marked: true, count: params.messageIds.length };
535
642
  }
536
643
  default:
537
- throw new Error(`Unknown method: ${method}`);
644
+ throw new SphereError(`Unknown method: ${method}`, "VALIDATION_ERROR");
538
645
  }
539
646
  }
540
647
  // ===========================================================================
541
648
  // Event Subscriptions
542
649
  // ===========================================================================
543
650
  handleSubscribe(eventName) {
544
- if (!eventName) throw new Error("Missing required parameter: event");
651
+ if (!eventName) throw new SphereError("Missing required parameter: event", "VALIDATION_ERROR");
545
652
  if (this.eventSubscriptions.has(eventName)) {
546
653
  return { subscribed: true, event: eventName };
547
654
  }
@@ -558,7 +665,7 @@ var ConnectHost = class {
558
665
  return { subscribed: true, event: eventName };
559
666
  }
560
667
  handleUnsubscribe(eventName) {
561
- if (!eventName) throw new Error("Missing required parameter: event");
668
+ if (!eventName) throw new SphereError("Missing required parameter: event", "VALIDATION_ERROR");
562
669
  const unsub = this.eventSubscriptions.get(eventName);
563
670
  if (unsub) {
564
671
  unsub();
@@ -724,7 +831,7 @@ var ConnectClient = class {
724
831
  // ===========================================================================
725
832
  /** Send a query request and return the result */
726
833
  async query(method, params) {
727
- if (!this.connected) throw new Error("Not connected");
834
+ if (!this.connected) throw new SphereError("Not connected", "NOT_INITIALIZED");
728
835
  const id = createRequestId();
729
836
  return new Promise((resolve, reject) => {
730
837
  const timer = setTimeout(() => {
@@ -751,7 +858,7 @@ var ConnectClient = class {
751
858
  // ===========================================================================
752
859
  /** Send an intent request. The wallet will open its UI for user confirmation. */
753
860
  async intent(action, params) {
754
- if (!this.connected) throw new Error("Not connected");
861
+ if (!this.connected) throw new SphereError("Not connected", "NOT_INITIALIZED");
755
862
  const id = createRequestId();
756
863
  return new Promise((resolve, reject) => {
757
864
  const timer = setTimeout(() => {
@@ -781,8 +888,7 @@ var ConnectClient = class {
781
888
  if (!this.eventHandlers.has(event)) {
782
889
  this.eventHandlers.set(event, /* @__PURE__ */ new Set());
783
890
  if (this.connected) {
784
- this.query(RPC_METHODS.SUBSCRIBE, { event }).catch(() => {
785
- });
891
+ this.query(RPC_METHODS.SUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event subscription failed", err));
786
892
  }
787
893
  }
788
894
  this.eventHandlers.get(event).add(handler);
@@ -793,8 +899,7 @@ var ConnectClient = class {
793
899
  if (handlers.size === 0) {
794
900
  this.eventHandlers.delete(event);
795
901
  if (this.connected) {
796
- this.query(RPC_METHODS.UNSUBSCRIBE, { event }).catch(() => {
797
- });
902
+ this.query(RPC_METHODS.UNSUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event unsubscription failed", err));
798
903
  }
799
904
  }
800
905
  }
@@ -822,7 +927,8 @@ var ConnectClient = class {
822
927
  for (const handler of handlers) {
823
928
  try {
824
929
  handler(msg.data);
825
- } catch {
930
+ } catch (err) {
931
+ logger.debug("Connect", "Event handler error", err);
826
932
  }
827
933
  }
828
934
  }