@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
@@ -1,3 +1,107 @@
1
+ // core/logger.ts
2
+ var LOGGER_KEY = "__sphere_sdk_logger__";
3
+ function getState() {
4
+ const g = globalThis;
5
+ if (!g[LOGGER_KEY]) {
6
+ g[LOGGER_KEY] = { debug: false, tags: {}, handler: null };
7
+ }
8
+ return g[LOGGER_KEY];
9
+ }
10
+ function isEnabled(tag) {
11
+ const state = getState();
12
+ if (tag in state.tags) return state.tags[tag];
13
+ return state.debug;
14
+ }
15
+ var logger = {
16
+ /**
17
+ * Configure the logger. Can be called multiple times (last write wins).
18
+ * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().
19
+ */
20
+ configure(config) {
21
+ const state = getState();
22
+ if (config.debug !== void 0) state.debug = config.debug;
23
+ if (config.handler !== void 0) state.handler = config.handler;
24
+ },
25
+ /**
26
+ * Enable/disable debug logging for a specific tag.
27
+ * Per-tag setting overrides the global debug flag.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * logger.setTagDebug('Nostr', true); // enable only Nostr logs
32
+ * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true
33
+ * ```
34
+ */
35
+ setTagDebug(tag, enabled) {
36
+ getState().tags[tag] = enabled;
37
+ },
38
+ /**
39
+ * Clear per-tag override, falling back to global debug flag.
40
+ */
41
+ clearTagDebug(tag) {
42
+ delete getState().tags[tag];
43
+ },
44
+ /** Returns true if debug mode is enabled for the given tag (or globally). */
45
+ isDebugEnabled(tag) {
46
+ if (tag) return isEnabled(tag);
47
+ return getState().debug;
48
+ },
49
+ /**
50
+ * Debug-level log. Only shown when debug is enabled (globally or for this tag).
51
+ * Use for detailed operational information.
52
+ */
53
+ debug(tag, message, ...args) {
54
+ if (!isEnabled(tag)) return;
55
+ const state = getState();
56
+ if (state.handler) {
57
+ state.handler("debug", tag, message, ...args);
58
+ } else {
59
+ console.log(`[${tag}]`, message, ...args);
60
+ }
61
+ },
62
+ /**
63
+ * Warning-level log. ALWAYS shown regardless of debug flag.
64
+ * Use for important but non-critical issues (timeouts, retries, degraded state).
65
+ */
66
+ warn(tag, message, ...args) {
67
+ const state = getState();
68
+ if (state.handler) {
69
+ state.handler("warn", tag, message, ...args);
70
+ } else {
71
+ console.warn(`[${tag}]`, message, ...args);
72
+ }
73
+ },
74
+ /**
75
+ * Error-level log. ALWAYS shown regardless of debug flag.
76
+ * Use for critical failures that should never be silenced.
77
+ */
78
+ error(tag, message, ...args) {
79
+ const state = getState();
80
+ if (state.handler) {
81
+ state.handler("error", tag, message, ...args);
82
+ } else {
83
+ console.error(`[${tag}]`, message, ...args);
84
+ }
85
+ },
86
+ /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */
87
+ reset() {
88
+ const g = globalThis;
89
+ delete g[LOGGER_KEY];
90
+ }
91
+ };
92
+
93
+ // core/errors.ts
94
+ var SphereError = class extends Error {
95
+ code;
96
+ cause;
97
+ constructor(message, code, cause) {
98
+ super(message);
99
+ this.name = "SphereError";
100
+ this.code = code;
101
+ this.cause = cause;
102
+ }
103
+ };
104
+
1
105
  // constants.ts
2
106
  var STORAGE_KEYS_GLOBAL = {
3
107
  /** Encrypted BIP39 mnemonic */
@@ -262,7 +366,7 @@ var ConnectHost = class {
262
366
  return;
263
367
  }
264
368
  } catch (error) {
265
- console.warn("[ConnectHost] Error handling message:", error);
369
+ logger.warn("ConnectHost", "Error handling message:", error);
266
370
  }
267
371
  }
268
372
  // ===========================================================================
@@ -337,7 +441,7 @@ var ConnectHost = class {
337
441
  this.revokeSession();
338
442
  this.sendResult(msg.id, { disconnected: true });
339
443
  if (disconnectedSession && this.config.onDisconnect) {
340
- Promise.resolve(this.config.onDisconnect(disconnectedSession)).catch(console.warn);
444
+ Promise.resolve(this.config.onDisconnect(disconnectedSession)).catch((err) => logger.warn("Connect", "onDisconnect handler error", err));
341
445
  }
342
446
  return;
343
447
  }
@@ -409,17 +513,17 @@ var ConnectHost = class {
409
513
  return this.sphere.payments.getHistory();
410
514
  case RPC_METHODS.L1_GET_BALANCE:
411
515
  if (!this.sphere.payments.l1) {
412
- throw new Error("L1 module not available");
516
+ throw new SphereError("L1 module not available", "MODULE_NOT_AVAILABLE");
413
517
  }
414
518
  return this.sphere.payments.l1.getBalance();
415
519
  case RPC_METHODS.L1_GET_HISTORY:
416
520
  if (!this.sphere.payments.l1) {
417
- throw new Error("L1 module not available");
521
+ throw new SphereError("L1 module not available", "MODULE_NOT_AVAILABLE");
418
522
  }
419
523
  return this.sphere.payments.l1.getHistory(params.limit);
420
524
  case RPC_METHODS.RESOLVE:
421
525
  if (!params.identifier) {
422
- throw new Error("Missing required parameter: identifier");
526
+ throw new SphereError("Missing required parameter: identifier", "VALIDATION_ERROR");
423
527
  }
424
528
  return this.sphere.resolve(params.identifier);
425
529
  case RPC_METHODS.SUBSCRIBE:
@@ -427,7 +531,7 @@ var ConnectHost = class {
427
531
  case RPC_METHODS.UNSUBSCRIBE:
428
532
  return this.handleUnsubscribe(params.event);
429
533
  case RPC_METHODS.GET_CONVERSATIONS: {
430
- if (!this.sphere.communications) throw new Error("Communications module not available");
534
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
431
535
  const convos = this.sphere.communications.getConversations();
432
536
  const result = [];
433
537
  const needsResolve = [];
@@ -450,7 +554,10 @@ var ConnectHost = class {
450
554
  if (needsResolve.length > 0) {
451
555
  const resolved = await Promise.all(
452
556
  needsResolve.map(
453
- ({ peerPubkey }) => this.sphere.communications.resolvePeerNametag(peerPubkey).catch(() => void 0)
557
+ ({ peerPubkey }) => this.sphere.communications.resolvePeerNametag(peerPubkey).catch((err) => {
558
+ logger.debug("Connect", "Peer nametag resolution failed", err);
559
+ return void 0;
560
+ })
454
561
  )
455
562
  );
456
563
  for (let i = 0; i < needsResolve.length; i++) {
@@ -463,8 +570,8 @@ var ConnectHost = class {
463
570
  return result;
464
571
  }
465
572
  case RPC_METHODS.GET_MESSAGES: {
466
- if (!this.sphere.communications) throw new Error("Communications module not available");
467
- if (!params.peerPubkey) throw new Error("Missing required parameter: peerPubkey");
573
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
574
+ if (!params.peerPubkey) throw new SphereError("Missing required parameter: peerPubkey", "VALIDATION_ERROR");
468
575
  return this.sphere.communications.getConversationPage(
469
576
  params.peerPubkey,
470
577
  {
@@ -474,7 +581,7 @@ var ConnectHost = class {
474
581
  );
475
582
  }
476
583
  case RPC_METHODS.GET_DM_UNREAD_COUNT: {
477
- if (!this.sphere.communications) throw new Error("Communications module not available");
584
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
478
585
  return {
479
586
  unreadCount: this.sphere.communications.getUnreadCount(
480
587
  params.peerPubkey
@@ -482,22 +589,22 @@ var ConnectHost = class {
482
589
  };
483
590
  }
484
591
  case RPC_METHODS.MARK_AS_READ: {
485
- if (!this.sphere.communications) throw new Error("Communications module not available");
592
+ if (!this.sphere.communications) throw new SphereError("Communications module not available", "MODULE_NOT_AVAILABLE");
486
593
  if (!params.messageIds || !Array.isArray(params.messageIds)) {
487
- throw new Error("Missing required parameter: messageIds (string[])");
594
+ throw new SphereError("Missing required parameter: messageIds (string[])", "VALIDATION_ERROR");
488
595
  }
489
596
  await this.sphere.communications.markAsRead(params.messageIds);
490
597
  return { marked: true, count: params.messageIds.length };
491
598
  }
492
599
  default:
493
- throw new Error(`Unknown method: ${method}`);
600
+ throw new SphereError(`Unknown method: ${method}`, "VALIDATION_ERROR");
494
601
  }
495
602
  }
496
603
  // ===========================================================================
497
604
  // Event Subscriptions
498
605
  // ===========================================================================
499
606
  handleSubscribe(eventName) {
500
- if (!eventName) throw new Error("Missing required parameter: event");
607
+ if (!eventName) throw new SphereError("Missing required parameter: event", "VALIDATION_ERROR");
501
608
  if (this.eventSubscriptions.has(eventName)) {
502
609
  return { subscribed: true, event: eventName };
503
610
  }
@@ -514,7 +621,7 @@ var ConnectHost = class {
514
621
  return { subscribed: true, event: eventName };
515
622
  }
516
623
  handleUnsubscribe(eventName) {
517
- if (!eventName) throw new Error("Missing required parameter: event");
624
+ if (!eventName) throw new SphereError("Missing required parameter: event", "VALIDATION_ERROR");
518
625
  const unsub = this.eventSubscriptions.get(eventName);
519
626
  if (unsub) {
520
627
  unsub();
@@ -680,7 +787,7 @@ var ConnectClient = class {
680
787
  // ===========================================================================
681
788
  /** Send a query request and return the result */
682
789
  async query(method, params) {
683
- if (!this.connected) throw new Error("Not connected");
790
+ if (!this.connected) throw new SphereError("Not connected", "NOT_INITIALIZED");
684
791
  const id = createRequestId();
685
792
  return new Promise((resolve, reject) => {
686
793
  const timer = setTimeout(() => {
@@ -707,7 +814,7 @@ var ConnectClient = class {
707
814
  // ===========================================================================
708
815
  /** Send an intent request. The wallet will open its UI for user confirmation. */
709
816
  async intent(action, params) {
710
- if (!this.connected) throw new Error("Not connected");
817
+ if (!this.connected) throw new SphereError("Not connected", "NOT_INITIALIZED");
711
818
  const id = createRequestId();
712
819
  return new Promise((resolve, reject) => {
713
820
  const timer = setTimeout(() => {
@@ -737,8 +844,7 @@ var ConnectClient = class {
737
844
  if (!this.eventHandlers.has(event)) {
738
845
  this.eventHandlers.set(event, /* @__PURE__ */ new Set());
739
846
  if (this.connected) {
740
- this.query(RPC_METHODS.SUBSCRIBE, { event }).catch(() => {
741
- });
847
+ this.query(RPC_METHODS.SUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event subscription failed", err));
742
848
  }
743
849
  }
744
850
  this.eventHandlers.get(event).add(handler);
@@ -749,8 +855,7 @@ var ConnectClient = class {
749
855
  if (handlers.size === 0) {
750
856
  this.eventHandlers.delete(event);
751
857
  if (this.connected) {
752
- this.query(RPC_METHODS.UNSUBSCRIBE, { event }).catch(() => {
753
- });
858
+ this.query(RPC_METHODS.UNSUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event unsubscription failed", err));
754
859
  }
755
860
  }
756
861
  }
@@ -778,7 +883,8 @@ var ConnectClient = class {
778
883
  for (const handler of handlers) {
779
884
  try {
780
885
  handler(msg.data);
781
- } catch {
886
+ } catch (err) {
887
+ logger.debug("Connect", "Event handler error", err);
782
888
  }
783
889
  }
784
890
  }