@unicitylabs/sphere-sdk 0.4.0 → 0.4.3

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.
package/dist/index.d.cts CHANGED
@@ -3063,6 +3063,13 @@ declare class PaymentsModule {
3063
3063
  * Remove all nametag data from memory and storage.
3064
3064
  */
3065
3065
  clearNametag(): Promise<void>;
3066
+ /**
3067
+ * Reload nametag data from storage providers into memory.
3068
+ *
3069
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
3070
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
3071
+ */
3072
+ private reloadNametagsFromStorage;
3066
3073
  /**
3067
3074
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
3068
3075
  * This creates the nametag token required for receiving tokens via PROXY addresses
package/dist/index.d.ts CHANGED
@@ -3063,6 +3063,13 @@ declare class PaymentsModule {
3063
3063
  * Remove all nametag data from memory and storage.
3064
3064
  */
3065
3065
  clearNametag(): Promise<void>;
3066
+ /**
3067
+ * Reload nametag data from storage providers into memory.
3068
+ *
3069
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
3070
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
3071
+ */
3072
+ private reloadNametagsFromStorage;
3066
3073
  /**
3067
3074
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
3068
3075
  * This creates the nametag token required for receiving tokens via PROXY addresses
package/dist/index.js CHANGED
@@ -6575,6 +6575,29 @@ var PaymentsModule = class _PaymentsModule {
6575
6575
  this.nametags = [];
6576
6576
  await this.save();
6577
6577
  }
6578
+ /**
6579
+ * Reload nametag data from storage providers into memory.
6580
+ *
6581
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
6582
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
6583
+ */
6584
+ async reloadNametagsFromStorage() {
6585
+ const providers = this.getTokenStorageProviders();
6586
+ for (const [, provider] of providers) {
6587
+ try {
6588
+ const result = await provider.load();
6589
+ if (result.success && result.data) {
6590
+ const parsed = parseTxfStorageData(result.data);
6591
+ if (parsed.nametags.length > 0) {
6592
+ this.nametags = parsed.nametags;
6593
+ this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
6594
+ return;
6595
+ }
6596
+ }
6597
+ } catch {
6598
+ }
6599
+ }
6600
+ }
6578
6601
  /**
6579
6602
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
6580
6603
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -6699,11 +6722,15 @@ var PaymentsModule = class _PaymentsModule {
6699
6722
  const localData = await this.createStorageData();
6700
6723
  let totalAdded = 0;
6701
6724
  let totalRemoved = 0;
6725
+ const savedNametags = [...this.nametags];
6702
6726
  for (const [providerId, provider] of providers) {
6703
6727
  try {
6704
6728
  const result = await provider.sync(localData);
6705
6729
  if (result.success && result.merged) {
6706
6730
  this.loadFromStorageData(result.merged);
6731
+ if (this.nametags.length === 0 && savedNametags.length > 0) {
6732
+ this.nametags = savedNametags;
6733
+ }
6707
6734
  totalAdded += result.added;
6708
6735
  totalRemoved += result.removed;
6709
6736
  }
@@ -7091,7 +7118,12 @@ var PaymentsModule = class _PaymentsModule {
7091
7118
  let nametagTokens = [];
7092
7119
  if (addressScheme === AddressScheme.PROXY) {
7093
7120
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
7094
- const proxyNametag = this.getNametag();
7121
+ let proxyNametag = this.getNametag();
7122
+ if (!proxyNametag?.token) {
7123
+ this.log("Nametag missing in memory, attempting reload from storage...");
7124
+ await this.reloadNametagsFromStorage();
7125
+ proxyNametag = this.getNametag();
7126
+ }
7095
7127
  if (!proxyNametag?.token) {
7096
7128
  throw new Error("Cannot finalize PROXY transfer - no nametag token");
7097
7129
  }
@@ -7696,13 +7728,14 @@ var CommunicationsModule = class {
7696
7728
  */
7697
7729
  async sendDM(recipient, content) {
7698
7730
  this.ensureInitialized();
7699
- const recipientPubkey = await this.resolveRecipient(recipient);
7700
- const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
7731
+ const resolved = await this.resolveRecipient(recipient);
7732
+ const eventId = await this.deps.transport.sendMessage(resolved.pubkey, content);
7701
7733
  const message = {
7702
7734
  id: eventId,
7703
7735
  senderPubkey: this.deps.identity.chainPubkey,
7704
7736
  senderNametag: this.deps.identity.nametag,
7705
- recipientPubkey,
7737
+ recipientPubkey: resolved.pubkey,
7738
+ ...resolved.nametag ? { recipientNametag: resolved.nametag } : {},
7706
7739
  content,
7707
7740
  timestamp: Date.now(),
7708
7741
  isRead: false
@@ -7820,12 +7853,12 @@ var CommunicationsModule = class {
7820
7853
  */
7821
7854
  async sendComposingIndicator(recipientPubkeyOrNametag) {
7822
7855
  this.ensureInitialized();
7823
- const recipientPubkey = await this.resolveRecipient(recipientPubkeyOrNametag);
7856
+ const resolved = await this.resolveRecipient(recipientPubkeyOrNametag);
7824
7857
  const content = JSON.stringify({
7825
7858
  senderNametag: this.deps.identity.nametag,
7826
7859
  expiresIn: 3e4
7827
7860
  });
7828
- await this.deps.transport.sendComposingIndicator?.(recipientPubkey, content);
7861
+ await this.deps.transport.sendComposingIndicator?.(resolved.pubkey, content);
7829
7862
  }
7830
7863
  /**
7831
7864
  * Subscribe to incoming composing indicators
@@ -8013,13 +8046,14 @@ var CommunicationsModule = class {
8013
8046
  // ===========================================================================
8014
8047
  async resolveRecipient(recipient) {
8015
8048
  if (recipient.startsWith("@")) {
8016
- const pubkey = await this.deps.transport.resolveNametag?.(recipient.slice(1));
8049
+ const nametag = recipient.slice(1);
8050
+ const pubkey = await this.deps.transport.resolveNametag?.(nametag);
8017
8051
  if (!pubkey) {
8018
8052
  throw new Error(`Nametag not found: ${recipient}`);
8019
8053
  }
8020
- return pubkey;
8054
+ return { pubkey, nametag };
8021
8055
  }
8022
- return recipient;
8056
+ return { pubkey: recipient };
8023
8057
  }
8024
8058
  ensureInitialized() {
8025
8059
  if (!this.deps) {
@@ -12704,14 +12738,17 @@ var Sphere = class _Sphere {
12704
12738
  if (!wasConnected) {
12705
12739
  await storage.connect();
12706
12740
  }
12707
- const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12708
- if (mnemonic) return true;
12709
- const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12710
- if (masterKey) return true;
12711
- if (!wasConnected) {
12712
- await storage.disconnect();
12741
+ try {
12742
+ const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12743
+ if (mnemonic) return true;
12744
+ const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12745
+ if (masterKey) return true;
12746
+ return false;
12747
+ } finally {
12748
+ if (!wasConnected) {
12749
+ await storage.disconnect();
12750
+ }
12713
12751
  }
12714
- return false;
12715
12752
  } catch {
12716
12753
  return false;
12717
12754
  }
@@ -12845,6 +12882,9 @@ var Sphere = class _Sphere {
12845
12882
  if (await _Sphere.exists(options.storage)) {
12846
12883
  throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
12847
12884
  }
12885
+ if (!options.storage.isConnected()) {
12886
+ await options.storage.connect();
12887
+ }
12848
12888
  _Sphere.configureTokenRegistry(options.storage, options.network);
12849
12889
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
12850
12890
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -12896,6 +12936,9 @@ var Sphere = class _Sphere {
12896
12936
  marketConfig
12897
12937
  );
12898
12938
  sphere._password = options.password ?? null;
12939
+ if (!options.storage.isConnected()) {
12940
+ await options.storage.connect();
12941
+ }
12899
12942
  await sphere.loadIdentityFromStorage();
12900
12943
  await sphere.initializeProviders();
12901
12944
  await sphere.initializeModules();
@@ -13034,45 +13077,22 @@ var Sphere = class _Sphere {
13034
13077
  await _Sphere.instance.destroy();
13035
13078
  console.log("[Sphere.clear] Sphere instance destroyed");
13036
13079
  }
13080
+ console.log("[Sphere.clear] Clearing L1 vesting cache...");
13037
13081
  await vestingClassifier.destroy();
13038
- if (typeof indexedDB !== "undefined" && typeof indexedDB.databases === "function") {
13039
- console.log("[Sphere.clear] Deleting all sphere IndexedDB databases...");
13040
- try {
13041
- const dbs = await Promise.race([
13042
- indexedDB.databases(),
13043
- new Promise(
13044
- (_, reject) => setTimeout(() => reject(new Error("timeout")), 2e3)
13045
- )
13046
- ]);
13047
- const sphereDbs = dbs.filter((db) => db.name?.startsWith("sphere"));
13048
- if (sphereDbs.length > 0) {
13049
- await Promise.all(sphereDbs.map(
13050
- (db) => new Promise((resolve) => {
13051
- const req = indexedDB.deleteDatabase(db.name);
13052
- req.onsuccess = () => {
13053
- console.log(`[Sphere.clear] Deleted ${db.name}`);
13054
- resolve();
13055
- };
13056
- req.onerror = () => resolve();
13057
- req.onblocked = () => {
13058
- console.warn(`[Sphere.clear] deleteDatabase blocked: ${db.name}`);
13059
- resolve();
13060
- };
13061
- })
13062
- ));
13063
- }
13064
- console.log("[Sphere.clear] IndexedDB cleanup done");
13065
- } catch {
13066
- console.warn("[Sphere.clear] IndexedDB enumeration failed");
13067
- }
13068
- }
13082
+ console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
13083
+ await new Promise((r) => setTimeout(r, 50));
13069
13084
  if (tokenStorage?.clear) {
13085
+ console.log("[Sphere.clear] Clearing token storage...");
13070
13086
  try {
13071
13087
  await tokenStorage.clear();
13088
+ console.log("[Sphere.clear] Token storage cleared");
13072
13089
  } catch (err) {
13073
13090
  console.warn("[Sphere.clear] Token storage clear failed:", err);
13074
13091
  }
13092
+ } else {
13093
+ console.log("[Sphere.clear] No token storage provider to clear");
13075
13094
  }
13095
+ console.log("[Sphere.clear] Clearing KV storage...");
13076
13096
  if (!storage.isConnected()) {
13077
13097
  try {
13078
13098
  await storage.connect();
@@ -13081,7 +13101,11 @@ var Sphere = class _Sphere {
13081
13101
  }
13082
13102
  if (storage.isConnected()) {
13083
13103
  await storage.clear();
13104
+ console.log("[Sphere.clear] KV storage cleared");
13105
+ } else {
13106
+ console.log("[Sphere.clear] KV storage not connected, skipping");
13084
13107
  }
13108
+ console.log("[Sphere.clear] Done");
13085
13109
  }
13086
13110
  /**
13087
13111
  * Get current instance
@@ -13929,8 +13953,12 @@ var Sphere = class _Sphere {
13929
13953
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
13930
13954
  this._storage.setIdentity(this._identity);
13931
13955
  await this._transport.setIdentity(this._identity);
13932
- for (const provider of this._tokenStorageProviders.values()) {
13956
+ console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
13957
+ for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
13958
+ console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
13959
+ await provider.shutdown();
13933
13960
  provider.setIdentity(this._identity);
13961
+ console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
13934
13962
  await provider.initialize();
13935
13963
  }
13936
13964
  await this.reinitializeModulesForNewAddress();
@@ -14012,6 +14040,9 @@ var Sphere = class _Sphere {
14012
14040
  await this._communications.load();
14013
14041
  await this._groupChat?.load();
14014
14042
  await this._market?.load();
14043
+ this._payments.sync().catch((err) => {
14044
+ console.warn("[Sphere] Post-switch sync failed:", err);
14045
+ });
14015
14046
  }
14016
14047
  /**
14017
14048
  * Derive address at a specific index