@unicitylabs/sphere-sdk 0.4.4 → 0.4.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 (37) hide show
  1. package/dist/connect/index.cjs +10 -10
  2. package/dist/connect/index.cjs.map +1 -1
  3. package/dist/connect/index.js +10 -10
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/core/index.cjs +55 -25
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +6 -0
  8. package/dist/core/index.d.ts +6 -0
  9. package/dist/core/index.js +55 -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 +55 -25
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +24 -18
  34. package/dist/index.d.ts +24 -18
  35. package/dist/index.js +55 -25
  36. package/dist/index.js.map +1 -1
  37. package/package.json +1 -1
@@ -2621,6 +2621,7 @@ declare class CommunicationsModule {
2621
2621
  private dmHandlers;
2622
2622
  private composingHandlers;
2623
2623
  private broadcastHandlers;
2624
+ private initializedAt;
2624
2625
  constructor(config?: CommunicationsModuleConfig);
2625
2626
  /**
2626
2627
  * Initialize module with dependencies
@@ -2748,6 +2749,11 @@ declare class GroupChatModule {
2748
2749
  private destroyConnection;
2749
2750
  connect(): Promise<void>;
2750
2751
  getConnectionStatus(): boolean;
2752
+ /**
2753
+ * Refresh subscriptions after load() switched to a different address.
2754
+ * Clears old subscriptions, restores groups if needed, and re-subscribes.
2755
+ */
2756
+ private refreshSubscriptions;
2751
2757
  private doConnect;
2752
2758
  private scheduleReconnect;
2753
2759
  private subscribeToJoinedGroups;
@@ -2621,6 +2621,7 @@ declare class CommunicationsModule {
2621
2621
  private dmHandlers;
2622
2622
  private composingHandlers;
2623
2623
  private broadcastHandlers;
2624
+ private initializedAt;
2624
2625
  constructor(config?: CommunicationsModuleConfig);
2625
2626
  /**
2626
2627
  * Initialize module with dependencies
@@ -2748,6 +2749,11 @@ declare class GroupChatModule {
2748
2749
  private destroyConnection;
2749
2750
  connect(): Promise<void>;
2750
2751
  getConnectionStatus(): boolean;
2752
+ /**
2753
+ * Refresh subscriptions after load() switched to a different address.
2754
+ * Clears old subscriptions, restores groups if needed, and re-subscribes.
2755
+ */
2756
+ private refreshSubscriptions;
2751
2757
  private doConnect;
2752
2758
  private scheduleReconnect;
2753
2759
  private subscribeToJoinedGroups;
@@ -2348,15 +2348,7 @@ var STORAGE_KEYS_GLOBAL = {
2348
2348
  TRACKED_ADDRESSES: "tracked_addresses",
2349
2349
  /** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
2350
2350
  LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
2351
- /** Group chat: joined groups */
2352
- GROUP_CHAT_GROUPS: "group_chat_groups",
2353
- /** Group chat: messages */
2354
- GROUP_CHAT_MESSAGES: "group_chat_messages",
2355
- /** Group chat: members */
2356
- GROUP_CHAT_MEMBERS: "group_chat_members",
2357
- /** Group chat: processed event IDs for deduplication */
2358
- GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events",
2359
- /** Group chat: last used relay URL (stale data detection) */
2351
+ /** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
2360
2352
  GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
2361
2353
  /** Cached token registry JSON (fetched from remote) */
2362
2354
  TOKEN_REGISTRY_CACHE: "token_registry_cache",
@@ -2379,7 +2371,15 @@ var STORAGE_KEYS_ADDRESS = {
2379
2371
  /** Transaction history for this address */
2380
2372
  TRANSACTION_HISTORY: "transaction_history",
2381
2373
  /** Pending V5 finalization tokens (unconfirmed instant split tokens) */
2382
- PENDING_V5_TOKENS: "pending_v5_tokens"
2374
+ PENDING_V5_TOKENS: "pending_v5_tokens",
2375
+ /** Group chat: joined groups for this address */
2376
+ GROUP_CHAT_GROUPS: "group_chat_groups",
2377
+ /** Group chat: messages for this address */
2378
+ GROUP_CHAT_MESSAGES: "group_chat_messages",
2379
+ /** Group chat: members for this address */
2380
+ GROUP_CHAT_MEMBERS: "group_chat_members",
2381
+ /** Group chat: processed event IDs for deduplication */
2382
+ GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
2383
2383
  };
2384
2384
  var STORAGE_KEYS = {
2385
2385
  ...STORAGE_KEYS_GLOBAL,
@@ -7350,6 +7350,8 @@ var CommunicationsModule = class {
7350
7350
  dmHandlers = /* @__PURE__ */ new Set();
7351
7351
  composingHandlers = /* @__PURE__ */ new Set();
7352
7352
  broadcastHandlers = /* @__PURE__ */ new Set();
7353
+ // Timestamp of module initialization — messages older than this are historical
7354
+ initializedAt = 0;
7353
7355
  constructor(config) {
7354
7356
  this.config = {
7355
7357
  autoSave: config?.autoSave ?? true,
@@ -7368,6 +7370,7 @@ var CommunicationsModule = class {
7368
7370
  this.unsubscribeMessages?.();
7369
7371
  this.unsubscribeComposing?.();
7370
7372
  this.deps = deps;
7373
+ this.initializedAt = Date.now();
7371
7374
  this.unsubscribeMessages = deps.transport.onMessage((msg) => {
7372
7375
  this.handleIncomingMessage(msg);
7373
7376
  });
@@ -7659,6 +7662,7 @@ var CommunicationsModule = class {
7659
7662
  // Private: Message Handling
7660
7663
  // ===========================================================================
7661
7664
  handleIncomingMessage(msg) {
7665
+ const isHistorical = msg.timestamp < this.initializedAt;
7662
7666
  if (msg.isSelfWrap && msg.recipientTransportPubkey) {
7663
7667
  if (this.messages.has(msg.id)) return;
7664
7668
  const message2 = {
@@ -7668,7 +7672,7 @@ var CommunicationsModule = class {
7668
7672
  recipientPubkey: msg.recipientTransportPubkey,
7669
7673
  content: msg.content,
7670
7674
  timestamp: msg.timestamp,
7671
- isRead: false
7675
+ isRead: isHistorical
7672
7676
  };
7673
7677
  this.messages.set(message2.id, message2);
7674
7678
  this.deps.emitEvent("message:dm", message2);
@@ -7686,7 +7690,7 @@ var CommunicationsModule = class {
7686
7690
  recipientPubkey: this.deps.identity.chainPubkey,
7687
7691
  content: msg.content,
7688
7692
  timestamp: msg.timestamp,
7689
- isRead: false
7693
+ isRead: isHistorical
7690
7694
  };
7691
7695
  this.messages.set(message.id, message);
7692
7696
  this.deps.emitEvent("message:dm", message);
@@ -7862,22 +7866,24 @@ var GroupChatModule = class {
7862
7866
  async load() {
7863
7867
  this.ensureInitialized();
7864
7868
  const storage = this.deps.storage;
7865
- const groupsJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS);
7869
+ this.groups.clear();
7870
+ this.messages.clear();
7871
+ this.members.clear();
7872
+ this.processedEventIds.clear();
7873
+ const groupsJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS);
7866
7874
  if (groupsJson) {
7867
7875
  try {
7868
7876
  const parsed = JSON.parse(groupsJson);
7869
- this.groups.clear();
7870
7877
  for (const g of parsed) {
7871
7878
  this.groups.set(g.id, g);
7872
7879
  }
7873
7880
  } catch {
7874
7881
  }
7875
7882
  }
7876
- const messagesJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES);
7883
+ const messagesJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES);
7877
7884
  if (messagesJson) {
7878
7885
  try {
7879
7886
  const parsed = JSON.parse(messagesJson);
7880
- this.messages.clear();
7881
7887
  for (const m of parsed) {
7882
7888
  const groupId = m.groupId;
7883
7889
  if (!this.messages.has(groupId)) {
@@ -7888,11 +7894,10 @@ var GroupChatModule = class {
7888
7894
  } catch {
7889
7895
  }
7890
7896
  }
7891
- const membersJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS);
7897
+ const membersJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS);
7892
7898
  if (membersJson) {
7893
7899
  try {
7894
7900
  const parsed = JSON.parse(membersJson);
7895
- this.members.clear();
7896
7901
  for (const m of parsed) {
7897
7902
  const groupId = m.groupId;
7898
7903
  if (!this.members.has(groupId)) {
@@ -7903,7 +7908,7 @@ var GroupChatModule = class {
7903
7908
  } catch {
7904
7909
  }
7905
7910
  }
7906
- const processedJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS);
7911
+ const processedJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS);
7907
7912
  if (processedJson) {
7908
7913
  try {
7909
7914
  const parsed = JSON.parse(processedJson);
@@ -7957,7 +7962,10 @@ var GroupChatModule = class {
7957
7962
  // Connection
7958
7963
  // ===========================================================================
7959
7964
  async connect() {
7960
- if (this.connected) return;
7965
+ if (this.connected) {
7966
+ await this.refreshSubscriptions();
7967
+ return;
7968
+ }
7961
7969
  if (this.connectPromise) {
7962
7970
  return this.connectPromise;
7963
7971
  }
@@ -7971,6 +7979,28 @@ var GroupChatModule = class {
7971
7979
  getConnectionStatus() {
7972
7980
  return this.connected;
7973
7981
  }
7982
+ /**
7983
+ * Refresh subscriptions after load() switched to a different address.
7984
+ * Clears old subscriptions, restores groups if needed, and re-subscribes.
7985
+ */
7986
+ async refreshSubscriptions() {
7987
+ if (!this.client) return;
7988
+ for (const subId of this.subscriptionIds) {
7989
+ try {
7990
+ this.client.unsubscribe(subId);
7991
+ } catch {
7992
+ }
7993
+ }
7994
+ this.subscriptionIds = [];
7995
+ const secretKey = Buffer.from(this.deps.identity.privateKey, "hex");
7996
+ this.keyManager = NostrKeyManager.fromPrivateKey(secretKey);
7997
+ if (this.groups.size === 0) {
7998
+ await this.restoreJoinedGroups();
7999
+ } else {
8000
+ await this.subscribeToJoinedGroups();
8001
+ }
8002
+ this.deps.emitEvent("groupchat:connection", { connected: true });
8003
+ }
7974
8004
  async doConnect() {
7975
8005
  this.ensureInitialized();
7976
8006
  if (!this.keyManager) {
@@ -7986,12 +8016,12 @@ var GroupChatModule = class {
7986
8016
  await this.client.connect(...this.config.relays);
7987
8017
  this.connected = true;
7988
8018
  this.reconnectAttempts = 0;
7989
- this.deps.emitEvent("groupchat:connection", { connected: true });
7990
8019
  if (this.groups.size === 0) {
7991
8020
  await this.restoreJoinedGroups();
7992
8021
  } else {
7993
8022
  await this.subscribeToJoinedGroups();
7994
8023
  }
8024
+ this.deps.emitEvent("groupchat:connection", { connected: true });
7995
8025
  } catch (error) {
7996
8026
  console.error("[GroupChat] Failed to connect to relays", error);
7997
8027
  this.deps.emitEvent("groupchat:connection", { connected: false });
@@ -8974,7 +9004,7 @@ var GroupChatModule = class {
8974
9004
  async persistGroups() {
8975
9005
  if (!this.deps) return;
8976
9006
  const data = Array.from(this.groups.values());
8977
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS, JSON.stringify(data));
9007
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS, JSON.stringify(data));
8978
9008
  }
8979
9009
  async persistMessages() {
8980
9010
  if (!this.deps) return;
@@ -8982,7 +9012,7 @@ var GroupChatModule = class {
8982
9012
  for (const msgs of this.messages.values()) {
8983
9013
  allMessages.push(...msgs);
8984
9014
  }
8985
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
9015
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
8986
9016
  }
8987
9017
  async persistMembers() {
8988
9018
  if (!this.deps) return;
@@ -8990,12 +9020,12 @@ var GroupChatModule = class {
8990
9020
  for (const mems of this.members.values()) {
8991
9021
  allMembers.push(...mems);
8992
9022
  }
8993
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
9023
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
8994
9024
  }
8995
9025
  async persistProcessedEvents() {
8996
9026
  if (!this.deps) return;
8997
9027
  const arr = Array.from(this.processedEventIds);
8998
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
9028
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
8999
9029
  }
9000
9030
  // ===========================================================================
9001
9031
  // Private — Relay URL Change Detection