@unicitylabs/sphere-sdk 0.4.4 → 0.4.6

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 (37) hide show
  1. package/dist/connect/index.cjs +27 -10
  2. package/dist/connect/index.cjs.map +1 -1
  3. package/dist/connect/index.js +27 -10
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/core/index.cjs +72 -25
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +12 -0
  8. package/dist/core/index.d.ts +12 -0
  9. package/dist/core/index.js +72 -25
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/impl/browser/connect/index.cjs +10 -10
  12. package/dist/impl/browser/connect/index.cjs.map +1 -1
  13. package/dist/impl/browser/connect/index.js +10 -10
  14. package/dist/impl/browser/connect/index.js.map +1 -1
  15. package/dist/impl/browser/index.cjs +10 -10
  16. package/dist/impl/browser/index.cjs.map +1 -1
  17. package/dist/impl/browser/index.js +10 -10
  18. package/dist/impl/browser/index.js.map +1 -1
  19. package/dist/impl/browser/ipfs.cjs +10 -10
  20. package/dist/impl/browser/ipfs.cjs.map +1 -1
  21. package/dist/impl/browser/ipfs.js +10 -10
  22. package/dist/impl/browser/ipfs.js.map +1 -1
  23. package/dist/impl/nodejs/connect/index.cjs +10 -10
  24. package/dist/impl/nodejs/connect/index.cjs.map +1 -1
  25. package/dist/impl/nodejs/connect/index.js +10 -10
  26. package/dist/impl/nodejs/connect/index.js.map +1 -1
  27. package/dist/impl/nodejs/index.cjs +10 -10
  28. package/dist/impl/nodejs/index.cjs.map +1 -1
  29. package/dist/impl/nodejs/index.js +10 -10
  30. package/dist/impl/nodejs/index.js.map +1 -1
  31. package/dist/index.cjs +72 -25
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +30 -18
  34. package/dist/index.d.ts +30 -18
  35. package/dist/index.js +72 -25
  36. package/dist/index.js.map +1 -1
  37. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -2664,15 +2664,7 @@ var STORAGE_KEYS_GLOBAL = {
2664
2664
  TRACKED_ADDRESSES: "tracked_addresses",
2665
2665
  /** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
2666
2666
  LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
2667
- /** Group chat: joined groups */
2668
- GROUP_CHAT_GROUPS: "group_chat_groups",
2669
- /** Group chat: messages */
2670
- GROUP_CHAT_MESSAGES: "group_chat_messages",
2671
- /** Group chat: members */
2672
- GROUP_CHAT_MEMBERS: "group_chat_members",
2673
- /** Group chat: processed event IDs for deduplication */
2674
- GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events",
2675
- /** Group chat: last used relay URL (stale data detection) */
2667
+ /** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
2676
2668
  GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
2677
2669
  /** Cached token registry JSON (fetched from remote) */
2678
2670
  TOKEN_REGISTRY_CACHE: "token_registry_cache",
@@ -2695,7 +2687,15 @@ var STORAGE_KEYS_ADDRESS = {
2695
2687
  /** Transaction history for this address */
2696
2688
  TRANSACTION_HISTORY: "transaction_history",
2697
2689
  /** Pending V5 finalization tokens (unconfirmed instant split tokens) */
2698
- PENDING_V5_TOKENS: "pending_v5_tokens"
2690
+ PENDING_V5_TOKENS: "pending_v5_tokens",
2691
+ /** Group chat: joined groups for this address */
2692
+ GROUP_CHAT_GROUPS: "group_chat_groups",
2693
+ /** Group chat: messages for this address */
2694
+ GROUP_CHAT_MESSAGES: "group_chat_messages",
2695
+ /** Group chat: members for this address */
2696
+ GROUP_CHAT_MEMBERS: "group_chat_members",
2697
+ /** Group chat: processed event IDs for deduplication */
2698
+ GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
2699
2699
  };
2700
2700
  var STORAGE_KEYS = {
2701
2701
  ...STORAGE_KEYS_GLOBAL,
@@ -7806,6 +7806,8 @@ var CommunicationsModule = class {
7806
7806
  dmHandlers = /* @__PURE__ */ new Set();
7807
7807
  composingHandlers = /* @__PURE__ */ new Set();
7808
7808
  broadcastHandlers = /* @__PURE__ */ new Set();
7809
+ // Timestamp of module initialization — messages older than this are historical
7810
+ initializedAt = 0;
7809
7811
  constructor(config) {
7810
7812
  this.config = {
7811
7813
  autoSave: config?.autoSave ?? true,
@@ -7824,6 +7826,7 @@ var CommunicationsModule = class {
7824
7826
  this.unsubscribeMessages?.();
7825
7827
  this.unsubscribeComposing?.();
7826
7828
  this.deps = deps;
7829
+ this.initializedAt = Date.now();
7827
7830
  this.unsubscribeMessages = deps.transport.onMessage((msg) => {
7828
7831
  this.handleIncomingMessage(msg);
7829
7832
  });
@@ -8112,9 +8115,27 @@ var CommunicationsModule = class {
8112
8115
  return () => this.broadcastHandlers.delete(handler);
8113
8116
  }
8114
8117
  // ===========================================================================
8118
+ // Public API - Peer Resolution
8119
+ // ===========================================================================
8120
+ /**
8121
+ * Resolve a peer's nametag by their transport pubkey.
8122
+ * Uses transport.resolveTransportPubkeyInfo() for live lookup from relay binding events.
8123
+ * Returns undefined if transport doesn't support resolution or peer has no nametag.
8124
+ */
8125
+ async resolvePeerNametag(peerPubkey) {
8126
+ if (!this.deps?.transport.resolveTransportPubkeyInfo) return void 0;
8127
+ try {
8128
+ const info = await this.deps.transport.resolveTransportPubkeyInfo(peerPubkey);
8129
+ return info?.nametag;
8130
+ } catch {
8131
+ return void 0;
8132
+ }
8133
+ }
8134
+ // ===========================================================================
8115
8135
  // Private: Message Handling
8116
8136
  // ===========================================================================
8117
8137
  handleIncomingMessage(msg) {
8138
+ const isHistorical = msg.timestamp < this.initializedAt;
8118
8139
  if (msg.isSelfWrap && msg.recipientTransportPubkey) {
8119
8140
  if (this.messages.has(msg.id)) return;
8120
8141
  const message2 = {
@@ -8124,7 +8145,7 @@ var CommunicationsModule = class {
8124
8145
  recipientPubkey: msg.recipientTransportPubkey,
8125
8146
  content: msg.content,
8126
8147
  timestamp: msg.timestamp,
8127
- isRead: false
8148
+ isRead: isHistorical
8128
8149
  };
8129
8150
  this.messages.set(message2.id, message2);
8130
8151
  this.deps.emitEvent("message:dm", message2);
@@ -8142,7 +8163,7 @@ var CommunicationsModule = class {
8142
8163
  recipientPubkey: this.deps.identity.chainPubkey,
8143
8164
  content: msg.content,
8144
8165
  timestamp: msg.timestamp,
8145
- isRead: false
8166
+ isRead: isHistorical
8146
8167
  };
8147
8168
  this.messages.set(message.id, message);
8148
8169
  this.deps.emitEvent("message:dm", message);
@@ -8314,22 +8335,24 @@ var GroupChatModule = class {
8314
8335
  async load() {
8315
8336
  this.ensureInitialized();
8316
8337
  const storage = this.deps.storage;
8317
- const groupsJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS);
8338
+ this.groups.clear();
8339
+ this.messages.clear();
8340
+ this.members.clear();
8341
+ this.processedEventIds.clear();
8342
+ const groupsJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS);
8318
8343
  if (groupsJson) {
8319
8344
  try {
8320
8345
  const parsed = JSON.parse(groupsJson);
8321
- this.groups.clear();
8322
8346
  for (const g of parsed) {
8323
8347
  this.groups.set(g.id, g);
8324
8348
  }
8325
8349
  } catch {
8326
8350
  }
8327
8351
  }
8328
- const messagesJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES);
8352
+ const messagesJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES);
8329
8353
  if (messagesJson) {
8330
8354
  try {
8331
8355
  const parsed = JSON.parse(messagesJson);
8332
- this.messages.clear();
8333
8356
  for (const m of parsed) {
8334
8357
  const groupId = m.groupId;
8335
8358
  if (!this.messages.has(groupId)) {
@@ -8340,11 +8363,10 @@ var GroupChatModule = class {
8340
8363
  } catch {
8341
8364
  }
8342
8365
  }
8343
- const membersJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS);
8366
+ const membersJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS);
8344
8367
  if (membersJson) {
8345
8368
  try {
8346
8369
  const parsed = JSON.parse(membersJson);
8347
- this.members.clear();
8348
8370
  for (const m of parsed) {
8349
8371
  const groupId = m.groupId;
8350
8372
  if (!this.members.has(groupId)) {
@@ -8355,7 +8377,7 @@ var GroupChatModule = class {
8355
8377
  } catch {
8356
8378
  }
8357
8379
  }
8358
- const processedJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS);
8380
+ const processedJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS);
8359
8381
  if (processedJson) {
8360
8382
  try {
8361
8383
  const parsed = JSON.parse(processedJson);
@@ -8409,7 +8431,10 @@ var GroupChatModule = class {
8409
8431
  // Connection
8410
8432
  // ===========================================================================
8411
8433
  async connect() {
8412
- if (this.connected) return;
8434
+ if (this.connected) {
8435
+ await this.refreshSubscriptions();
8436
+ return;
8437
+ }
8413
8438
  if (this.connectPromise) {
8414
8439
  return this.connectPromise;
8415
8440
  }
@@ -8423,6 +8448,28 @@ var GroupChatModule = class {
8423
8448
  getConnectionStatus() {
8424
8449
  return this.connected;
8425
8450
  }
8451
+ /**
8452
+ * Refresh subscriptions after load() switched to a different address.
8453
+ * Clears old subscriptions, restores groups if needed, and re-subscribes.
8454
+ */
8455
+ async refreshSubscriptions() {
8456
+ if (!this.client) return;
8457
+ for (const subId of this.subscriptionIds) {
8458
+ try {
8459
+ this.client.unsubscribe(subId);
8460
+ } catch {
8461
+ }
8462
+ }
8463
+ this.subscriptionIds = [];
8464
+ const secretKey = Buffer.from(this.deps.identity.privateKey, "hex");
8465
+ this.keyManager = import_nostr_js_sdk2.NostrKeyManager.fromPrivateKey(secretKey);
8466
+ if (this.groups.size === 0) {
8467
+ await this.restoreJoinedGroups();
8468
+ } else {
8469
+ await this.subscribeToJoinedGroups();
8470
+ }
8471
+ this.deps.emitEvent("groupchat:connection", { connected: true });
8472
+ }
8426
8473
  async doConnect() {
8427
8474
  this.ensureInitialized();
8428
8475
  if (!this.keyManager) {
@@ -8438,12 +8485,12 @@ var GroupChatModule = class {
8438
8485
  await this.client.connect(...this.config.relays);
8439
8486
  this.connected = true;
8440
8487
  this.reconnectAttempts = 0;
8441
- this.deps.emitEvent("groupchat:connection", { connected: true });
8442
8488
  if (this.groups.size === 0) {
8443
8489
  await this.restoreJoinedGroups();
8444
8490
  } else {
8445
8491
  await this.subscribeToJoinedGroups();
8446
8492
  }
8493
+ this.deps.emitEvent("groupchat:connection", { connected: true });
8447
8494
  } catch (error) {
8448
8495
  console.error("[GroupChat] Failed to connect to relays", error);
8449
8496
  this.deps.emitEvent("groupchat:connection", { connected: false });
@@ -9426,7 +9473,7 @@ var GroupChatModule = class {
9426
9473
  async persistGroups() {
9427
9474
  if (!this.deps) return;
9428
9475
  const data = Array.from(this.groups.values());
9429
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS, JSON.stringify(data));
9476
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS, JSON.stringify(data));
9430
9477
  }
9431
9478
  async persistMessages() {
9432
9479
  if (!this.deps) return;
@@ -9434,7 +9481,7 @@ var GroupChatModule = class {
9434
9481
  for (const msgs of this.messages.values()) {
9435
9482
  allMessages.push(...msgs);
9436
9483
  }
9437
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
9484
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
9438
9485
  }
9439
9486
  async persistMembers() {
9440
9487
  if (!this.deps) return;
@@ -9442,12 +9489,12 @@ var GroupChatModule = class {
9442
9489
  for (const mems of this.members.values()) {
9443
9490
  allMembers.push(...mems);
9444
9491
  }
9445
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
9492
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
9446
9493
  }
9447
9494
  async persistProcessedEvents() {
9448
9495
  if (!this.deps) return;
9449
9496
  const arr = Array.from(this.processedEventIds);
9450
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
9497
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
9451
9498
  }
9452
9499
  // ===========================================================================
9453
9500
  // Private — Relay URL Change Detection