@unicitylabs/sphere-sdk 0.4.0 → 0.4.2

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.
@@ -2419,6 +2419,13 @@ declare class PaymentsModule {
2419
2419
  * Remove all nametag data from memory and storage.
2420
2420
  */
2421
2421
  clearNametag(): Promise<void>;
2422
+ /**
2423
+ * Reload nametag data from storage providers into memory.
2424
+ *
2425
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
2426
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
2427
+ */
2428
+ private reloadNametagsFromStorage;
2422
2429
  /**
2423
2430
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
2424
2431
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -2419,6 +2419,13 @@ declare class PaymentsModule {
2419
2419
  * Remove all nametag data from memory and storage.
2420
2420
  */
2421
2421
  clearNametag(): Promise<void>;
2422
+ /**
2423
+ * Reload nametag data from storage providers into memory.
2424
+ *
2425
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
2426
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
2427
+ */
2428
+ private reloadNametagsFromStorage;
2422
2429
  /**
2423
2430
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
2424
2431
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -6280,6 +6280,29 @@ var PaymentsModule = class _PaymentsModule {
6280
6280
  this.nametags = [];
6281
6281
  await this.save();
6282
6282
  }
6283
+ /**
6284
+ * Reload nametag data from storage providers into memory.
6285
+ *
6286
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
6287
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
6288
+ */
6289
+ async reloadNametagsFromStorage() {
6290
+ const providers = this.getTokenStorageProviders();
6291
+ for (const [, provider] of providers) {
6292
+ try {
6293
+ const result = await provider.load();
6294
+ if (result.success && result.data) {
6295
+ const parsed = parseTxfStorageData(result.data);
6296
+ if (parsed.nametags.length > 0) {
6297
+ this.nametags = parsed.nametags;
6298
+ this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
6299
+ return;
6300
+ }
6301
+ }
6302
+ } catch {
6303
+ }
6304
+ }
6305
+ }
6283
6306
  /**
6284
6307
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
6285
6308
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -6404,11 +6427,15 @@ var PaymentsModule = class _PaymentsModule {
6404
6427
  const localData = await this.createStorageData();
6405
6428
  let totalAdded = 0;
6406
6429
  let totalRemoved = 0;
6430
+ const savedNametags = [...this.nametags];
6407
6431
  for (const [providerId, provider] of providers) {
6408
6432
  try {
6409
6433
  const result = await provider.sync(localData);
6410
6434
  if (result.success && result.merged) {
6411
6435
  this.loadFromStorageData(result.merged);
6436
+ if (this.nametags.length === 0 && savedNametags.length > 0) {
6437
+ this.nametags = savedNametags;
6438
+ }
6412
6439
  totalAdded += result.added;
6413
6440
  totalRemoved += result.removed;
6414
6441
  }
@@ -6796,7 +6823,12 @@ var PaymentsModule = class _PaymentsModule {
6796
6823
  let nametagTokens = [];
6797
6824
  if (addressScheme === AddressScheme.PROXY) {
6798
6825
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
6799
- const proxyNametag = this.getNametag();
6826
+ let proxyNametag = this.getNametag();
6827
+ if (!proxyNametag?.token) {
6828
+ this.log("Nametag missing in memory, attempting reload from storage...");
6829
+ await this.reloadNametagsFromStorage();
6830
+ proxyNametag = this.getNametag();
6831
+ }
6800
6832
  if (!proxyNametag?.token) {
6801
6833
  throw new Error("Cannot finalize PROXY transfer - no nametag token");
6802
6834
  }
@@ -7401,13 +7433,14 @@ var CommunicationsModule = class {
7401
7433
  */
7402
7434
  async sendDM(recipient, content) {
7403
7435
  this.ensureInitialized();
7404
- const recipientPubkey = await this.resolveRecipient(recipient);
7405
- const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
7436
+ const resolved = await this.resolveRecipient(recipient);
7437
+ const eventId = await this.deps.transport.sendMessage(resolved.pubkey, content);
7406
7438
  const message = {
7407
7439
  id: eventId,
7408
7440
  senderPubkey: this.deps.identity.chainPubkey,
7409
7441
  senderNametag: this.deps.identity.nametag,
7410
- recipientPubkey,
7442
+ recipientPubkey: resolved.pubkey,
7443
+ ...resolved.nametag ? { recipientNametag: resolved.nametag } : {},
7411
7444
  content,
7412
7445
  timestamp: Date.now(),
7413
7446
  isRead: false
@@ -7525,12 +7558,12 @@ var CommunicationsModule = class {
7525
7558
  */
7526
7559
  async sendComposingIndicator(recipientPubkeyOrNametag) {
7527
7560
  this.ensureInitialized();
7528
- const recipientPubkey = await this.resolveRecipient(recipientPubkeyOrNametag);
7561
+ const resolved = await this.resolveRecipient(recipientPubkeyOrNametag);
7529
7562
  const content = JSON.stringify({
7530
7563
  senderNametag: this.deps.identity.nametag,
7531
7564
  expiresIn: 3e4
7532
7565
  });
7533
- await this.deps.transport.sendComposingIndicator?.(recipientPubkey, content);
7566
+ await this.deps.transport.sendComposingIndicator?.(resolved.pubkey, content);
7534
7567
  }
7535
7568
  /**
7536
7569
  * Subscribe to incoming composing indicators
@@ -7718,13 +7751,14 @@ var CommunicationsModule = class {
7718
7751
  // ===========================================================================
7719
7752
  async resolveRecipient(recipient) {
7720
7753
  if (recipient.startsWith("@")) {
7721
- const pubkey = await this.deps.transport.resolveNametag?.(recipient.slice(1));
7754
+ const nametag = recipient.slice(1);
7755
+ const pubkey = await this.deps.transport.resolveNametag?.(nametag);
7722
7756
  if (!pubkey) {
7723
7757
  throw new Error(`Nametag not found: ${recipient}`);
7724
7758
  }
7725
- return pubkey;
7759
+ return { pubkey, nametag };
7726
7760
  }
7727
- return recipient;
7761
+ return { pubkey: recipient };
7728
7762
  }
7729
7763
  ensureInitialized() {
7730
7764
  if (!this.deps) {
@@ -12824,45 +12858,22 @@ var Sphere = class _Sphere {
12824
12858
  await _Sphere.instance.destroy();
12825
12859
  console.log("[Sphere.clear] Sphere instance destroyed");
12826
12860
  }
12861
+ console.log("[Sphere.clear] Clearing L1 vesting cache...");
12827
12862
  await vestingClassifier.destroy();
12828
- if (typeof indexedDB !== "undefined" && typeof indexedDB.databases === "function") {
12829
- console.log("[Sphere.clear] Deleting all sphere IndexedDB databases...");
12830
- try {
12831
- const dbs = await Promise.race([
12832
- indexedDB.databases(),
12833
- new Promise(
12834
- (_, reject) => setTimeout(() => reject(new Error("timeout")), 2e3)
12835
- )
12836
- ]);
12837
- const sphereDbs = dbs.filter((db) => db.name?.startsWith("sphere"));
12838
- if (sphereDbs.length > 0) {
12839
- await Promise.all(sphereDbs.map(
12840
- (db) => new Promise((resolve) => {
12841
- const req = indexedDB.deleteDatabase(db.name);
12842
- req.onsuccess = () => {
12843
- console.log(`[Sphere.clear] Deleted ${db.name}`);
12844
- resolve();
12845
- };
12846
- req.onerror = () => resolve();
12847
- req.onblocked = () => {
12848
- console.warn(`[Sphere.clear] deleteDatabase blocked: ${db.name}`);
12849
- resolve();
12850
- };
12851
- })
12852
- ));
12853
- }
12854
- console.log("[Sphere.clear] IndexedDB cleanup done");
12855
- } catch {
12856
- console.warn("[Sphere.clear] IndexedDB enumeration failed");
12857
- }
12858
- }
12863
+ console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
12864
+ await new Promise((r) => setTimeout(r, 50));
12859
12865
  if (tokenStorage?.clear) {
12866
+ console.log("[Sphere.clear] Clearing token storage...");
12860
12867
  try {
12861
12868
  await tokenStorage.clear();
12869
+ console.log("[Sphere.clear] Token storage cleared");
12862
12870
  } catch (err) {
12863
12871
  console.warn("[Sphere.clear] Token storage clear failed:", err);
12864
12872
  }
12873
+ } else {
12874
+ console.log("[Sphere.clear] No token storage provider to clear");
12865
12875
  }
12876
+ console.log("[Sphere.clear] Clearing KV storage...");
12866
12877
  if (!storage.isConnected()) {
12867
12878
  try {
12868
12879
  await storage.connect();
@@ -12871,7 +12882,11 @@ var Sphere = class _Sphere {
12871
12882
  }
12872
12883
  if (storage.isConnected()) {
12873
12884
  await storage.clear();
12885
+ console.log("[Sphere.clear] KV storage cleared");
12886
+ } else {
12887
+ console.log("[Sphere.clear] KV storage not connected, skipping");
12874
12888
  }
12889
+ console.log("[Sphere.clear] Done");
12875
12890
  }
12876
12891
  /**
12877
12892
  * Get current instance
@@ -13719,8 +13734,12 @@ var Sphere = class _Sphere {
13719
13734
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
13720
13735
  this._storage.setIdentity(this._identity);
13721
13736
  await this._transport.setIdentity(this._identity);
13722
- for (const provider of this._tokenStorageProviders.values()) {
13737
+ console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
13738
+ for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
13739
+ console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
13740
+ await provider.shutdown();
13723
13741
  provider.setIdentity(this._identity);
13742
+ console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
13724
13743
  await provider.initialize();
13725
13744
  }
13726
13745
  await this.reinitializeModulesForNewAddress();
@@ -13802,6 +13821,9 @@ var Sphere = class _Sphere {
13802
13821
  await this._communications.load();
13803
13822
  await this._groupChat?.load();
13804
13823
  await this._market?.load();
13824
+ this._payments.sync().catch((err) => {
13825
+ console.warn("[Sphere] Post-switch sync failed:", err);
13826
+ });
13805
13827
  }
13806
13828
  /**
13807
13829
  * Derive address at a specific index