@unicitylabs/sphere-sdk 0.4.3 → 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 (41) 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 +76 -28
  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 +76 -28
  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 +173 -108
  16. package/dist/impl/browser/index.cjs.map +1 -1
  17. package/dist/impl/browser/index.js +173 -108
  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 +76 -28
  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 +76 -28
  36. package/dist/index.js.map +1 -1
  37. package/dist/l1/index.cjs +21 -3
  38. package/dist/l1/index.cjs.map +1 -1
  39. package/dist/l1/index.js +21 -3
  40. package/dist/l1/index.js.map +1 -1
  41. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1011,6 +1011,12 @@ var VestingClassifier = class {
1011
1011
  };
1012
1012
  request.onsuccess = (event) => {
1013
1013
  this.db = event.target.result;
1014
+ this.db.onversionchange = () => {
1015
+ if (this.db) {
1016
+ this.db.close();
1017
+ this.db = null;
1018
+ }
1019
+ };
1014
1020
  resolve();
1015
1021
  };
1016
1022
  request.onerror = () => reject(request.error);
@@ -1219,9 +1225,21 @@ var VestingClassifier = class {
1219
1225
  if (typeof indexedDB !== "undefined") {
1220
1226
  await new Promise((resolve) => {
1221
1227
  const req = indexedDB.deleteDatabase(this.dbName);
1222
- req.onsuccess = () => resolve();
1223
- req.onerror = () => resolve();
1224
- req.onblocked = () => resolve();
1228
+ const timer = setTimeout(() => {
1229
+ console.warn(`[VestingClassifier] destroy: deleteDatabase timed out for ${this.dbName}`);
1230
+ resolve();
1231
+ }, 3e3);
1232
+ req.onsuccess = () => {
1233
+ clearTimeout(timer);
1234
+ resolve();
1235
+ };
1236
+ req.onerror = () => {
1237
+ clearTimeout(timer);
1238
+ resolve();
1239
+ };
1240
+ req.onblocked = () => {
1241
+ console.warn(`[VestingClassifier] destroy: deleteDatabase blocked for ${this.dbName}, waiting...`);
1242
+ };
1225
1243
  });
1226
1244
  }
1227
1245
  }
@@ -2646,15 +2664,7 @@ var STORAGE_KEYS_GLOBAL = {
2646
2664
  TRACKED_ADDRESSES: "tracked_addresses",
2647
2665
  /** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
2648
2666
  LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
2649
- /** Group chat: joined groups */
2650
- GROUP_CHAT_GROUPS: "group_chat_groups",
2651
- /** Group chat: messages */
2652
- GROUP_CHAT_MESSAGES: "group_chat_messages",
2653
- /** Group chat: members */
2654
- GROUP_CHAT_MEMBERS: "group_chat_members",
2655
- /** Group chat: processed event IDs for deduplication */
2656
- GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events",
2657
- /** 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 */
2658
2668
  GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
2659
2669
  /** Cached token registry JSON (fetched from remote) */
2660
2670
  TOKEN_REGISTRY_CACHE: "token_registry_cache",
@@ -2677,7 +2687,15 @@ var STORAGE_KEYS_ADDRESS = {
2677
2687
  /** Transaction history for this address */
2678
2688
  TRANSACTION_HISTORY: "transaction_history",
2679
2689
  /** Pending V5 finalization tokens (unconfirmed instant split tokens) */
2680
- 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"
2681
2699
  };
2682
2700
  var STORAGE_KEYS = {
2683
2701
  ...STORAGE_KEYS_GLOBAL,
@@ -7788,6 +7806,8 @@ var CommunicationsModule = class {
7788
7806
  dmHandlers = /* @__PURE__ */ new Set();
7789
7807
  composingHandlers = /* @__PURE__ */ new Set();
7790
7808
  broadcastHandlers = /* @__PURE__ */ new Set();
7809
+ // Timestamp of module initialization — messages older than this are historical
7810
+ initializedAt = 0;
7791
7811
  constructor(config) {
7792
7812
  this.config = {
7793
7813
  autoSave: config?.autoSave ?? true,
@@ -7806,6 +7826,7 @@ var CommunicationsModule = class {
7806
7826
  this.unsubscribeMessages?.();
7807
7827
  this.unsubscribeComposing?.();
7808
7828
  this.deps = deps;
7829
+ this.initializedAt = Date.now();
7809
7830
  this.unsubscribeMessages = deps.transport.onMessage((msg) => {
7810
7831
  this.handleIncomingMessage(msg);
7811
7832
  });
@@ -8097,6 +8118,7 @@ var CommunicationsModule = class {
8097
8118
  // Private: Message Handling
8098
8119
  // ===========================================================================
8099
8120
  handleIncomingMessage(msg) {
8121
+ const isHistorical = msg.timestamp < this.initializedAt;
8100
8122
  if (msg.isSelfWrap && msg.recipientTransportPubkey) {
8101
8123
  if (this.messages.has(msg.id)) return;
8102
8124
  const message2 = {
@@ -8106,7 +8128,7 @@ var CommunicationsModule = class {
8106
8128
  recipientPubkey: msg.recipientTransportPubkey,
8107
8129
  content: msg.content,
8108
8130
  timestamp: msg.timestamp,
8109
- isRead: false
8131
+ isRead: isHistorical
8110
8132
  };
8111
8133
  this.messages.set(message2.id, message2);
8112
8134
  this.deps.emitEvent("message:dm", message2);
@@ -8124,7 +8146,7 @@ var CommunicationsModule = class {
8124
8146
  recipientPubkey: this.deps.identity.chainPubkey,
8125
8147
  content: msg.content,
8126
8148
  timestamp: msg.timestamp,
8127
- isRead: false
8149
+ isRead: isHistorical
8128
8150
  };
8129
8151
  this.messages.set(message.id, message);
8130
8152
  this.deps.emitEvent("message:dm", message);
@@ -8296,22 +8318,24 @@ var GroupChatModule = class {
8296
8318
  async load() {
8297
8319
  this.ensureInitialized();
8298
8320
  const storage = this.deps.storage;
8299
- const groupsJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS);
8321
+ this.groups.clear();
8322
+ this.messages.clear();
8323
+ this.members.clear();
8324
+ this.processedEventIds.clear();
8325
+ const groupsJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS);
8300
8326
  if (groupsJson) {
8301
8327
  try {
8302
8328
  const parsed = JSON.parse(groupsJson);
8303
- this.groups.clear();
8304
8329
  for (const g of parsed) {
8305
8330
  this.groups.set(g.id, g);
8306
8331
  }
8307
8332
  } catch {
8308
8333
  }
8309
8334
  }
8310
- const messagesJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES);
8335
+ const messagesJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES);
8311
8336
  if (messagesJson) {
8312
8337
  try {
8313
8338
  const parsed = JSON.parse(messagesJson);
8314
- this.messages.clear();
8315
8339
  for (const m of parsed) {
8316
8340
  const groupId = m.groupId;
8317
8341
  if (!this.messages.has(groupId)) {
@@ -8322,11 +8346,10 @@ var GroupChatModule = class {
8322
8346
  } catch {
8323
8347
  }
8324
8348
  }
8325
- const membersJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS);
8349
+ const membersJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS);
8326
8350
  if (membersJson) {
8327
8351
  try {
8328
8352
  const parsed = JSON.parse(membersJson);
8329
- this.members.clear();
8330
8353
  for (const m of parsed) {
8331
8354
  const groupId = m.groupId;
8332
8355
  if (!this.members.has(groupId)) {
@@ -8337,7 +8360,7 @@ var GroupChatModule = class {
8337
8360
  } catch {
8338
8361
  }
8339
8362
  }
8340
- const processedJson = await storage.get(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS);
8363
+ const processedJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS);
8341
8364
  if (processedJson) {
8342
8365
  try {
8343
8366
  const parsed = JSON.parse(processedJson);
@@ -8391,7 +8414,10 @@ var GroupChatModule = class {
8391
8414
  // Connection
8392
8415
  // ===========================================================================
8393
8416
  async connect() {
8394
- if (this.connected) return;
8417
+ if (this.connected) {
8418
+ await this.refreshSubscriptions();
8419
+ return;
8420
+ }
8395
8421
  if (this.connectPromise) {
8396
8422
  return this.connectPromise;
8397
8423
  }
@@ -8405,6 +8431,28 @@ var GroupChatModule = class {
8405
8431
  getConnectionStatus() {
8406
8432
  return this.connected;
8407
8433
  }
8434
+ /**
8435
+ * Refresh subscriptions after load() switched to a different address.
8436
+ * Clears old subscriptions, restores groups if needed, and re-subscribes.
8437
+ */
8438
+ async refreshSubscriptions() {
8439
+ if (!this.client) return;
8440
+ for (const subId of this.subscriptionIds) {
8441
+ try {
8442
+ this.client.unsubscribe(subId);
8443
+ } catch {
8444
+ }
8445
+ }
8446
+ this.subscriptionIds = [];
8447
+ const secretKey = Buffer.from(this.deps.identity.privateKey, "hex");
8448
+ this.keyManager = import_nostr_js_sdk2.NostrKeyManager.fromPrivateKey(secretKey);
8449
+ if (this.groups.size === 0) {
8450
+ await this.restoreJoinedGroups();
8451
+ } else {
8452
+ await this.subscribeToJoinedGroups();
8453
+ }
8454
+ this.deps.emitEvent("groupchat:connection", { connected: true });
8455
+ }
8408
8456
  async doConnect() {
8409
8457
  this.ensureInitialized();
8410
8458
  if (!this.keyManager) {
@@ -8420,12 +8468,12 @@ var GroupChatModule = class {
8420
8468
  await this.client.connect(...this.config.relays);
8421
8469
  this.connected = true;
8422
8470
  this.reconnectAttempts = 0;
8423
- this.deps.emitEvent("groupchat:connection", { connected: true });
8424
8471
  if (this.groups.size === 0) {
8425
8472
  await this.restoreJoinedGroups();
8426
8473
  } else {
8427
8474
  await this.subscribeToJoinedGroups();
8428
8475
  }
8476
+ this.deps.emitEvent("groupchat:connection", { connected: true });
8429
8477
  } catch (error) {
8430
8478
  console.error("[GroupChat] Failed to connect to relays", error);
8431
8479
  this.deps.emitEvent("groupchat:connection", { connected: false });
@@ -9408,7 +9456,7 @@ var GroupChatModule = class {
9408
9456
  async persistGroups() {
9409
9457
  if (!this.deps) return;
9410
9458
  const data = Array.from(this.groups.values());
9411
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_GROUPS, JSON.stringify(data));
9459
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS, JSON.stringify(data));
9412
9460
  }
9413
9461
  async persistMessages() {
9414
9462
  if (!this.deps) return;
@@ -9416,7 +9464,7 @@ var GroupChatModule = class {
9416
9464
  for (const msgs of this.messages.values()) {
9417
9465
  allMessages.push(...msgs);
9418
9466
  }
9419
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
9467
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
9420
9468
  }
9421
9469
  async persistMembers() {
9422
9470
  if (!this.deps) return;
@@ -9424,12 +9472,12 @@ var GroupChatModule = class {
9424
9472
  for (const mems of this.members.values()) {
9425
9473
  allMembers.push(...mems);
9426
9474
  }
9427
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
9475
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
9428
9476
  }
9429
9477
  async persistProcessedEvents() {
9430
9478
  if (!this.deps) return;
9431
9479
  const arr = Array.from(this.processedEventIds);
9432
- await this.deps.storage.set(STORAGE_KEYS_GLOBAL.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
9480
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
9433
9481
  }
9434
9482
  // ===========================================================================
9435
9483
  // Private — Relay URL Change Detection