@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.cjs CHANGED
@@ -6736,6 +6736,29 @@ var PaymentsModule = class _PaymentsModule {
6736
6736
  this.nametags = [];
6737
6737
  await this.save();
6738
6738
  }
6739
+ /**
6740
+ * Reload nametag data from storage providers into memory.
6741
+ *
6742
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
6743
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
6744
+ */
6745
+ async reloadNametagsFromStorage() {
6746
+ const providers = this.getTokenStorageProviders();
6747
+ for (const [, provider] of providers) {
6748
+ try {
6749
+ const result = await provider.load();
6750
+ if (result.success && result.data) {
6751
+ const parsed = parseTxfStorageData(result.data);
6752
+ if (parsed.nametags.length > 0) {
6753
+ this.nametags = parsed.nametags;
6754
+ this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
6755
+ return;
6756
+ }
6757
+ }
6758
+ } catch {
6759
+ }
6760
+ }
6761
+ }
6739
6762
  /**
6740
6763
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
6741
6764
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -6860,11 +6883,15 @@ var PaymentsModule = class _PaymentsModule {
6860
6883
  const localData = await this.createStorageData();
6861
6884
  let totalAdded = 0;
6862
6885
  let totalRemoved = 0;
6886
+ const savedNametags = [...this.nametags];
6863
6887
  for (const [providerId, provider] of providers) {
6864
6888
  try {
6865
6889
  const result = await provider.sync(localData);
6866
6890
  if (result.success && result.merged) {
6867
6891
  this.loadFromStorageData(result.merged);
6892
+ if (this.nametags.length === 0 && savedNametags.length > 0) {
6893
+ this.nametags = savedNametags;
6894
+ }
6868
6895
  totalAdded += result.added;
6869
6896
  totalRemoved += result.removed;
6870
6897
  }
@@ -7252,7 +7279,12 @@ var PaymentsModule = class _PaymentsModule {
7252
7279
  let nametagTokens = [];
7253
7280
  if (addressScheme === import_AddressScheme.AddressScheme.PROXY) {
7254
7281
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
7255
- const proxyNametag = this.getNametag();
7282
+ let proxyNametag = this.getNametag();
7283
+ if (!proxyNametag?.token) {
7284
+ this.log("Nametag missing in memory, attempting reload from storage...");
7285
+ await this.reloadNametagsFromStorage();
7286
+ proxyNametag = this.getNametag();
7287
+ }
7256
7288
  if (!proxyNametag?.token) {
7257
7289
  throw new Error("Cannot finalize PROXY transfer - no nametag token");
7258
7290
  }
@@ -7857,13 +7889,14 @@ var CommunicationsModule = class {
7857
7889
  */
7858
7890
  async sendDM(recipient, content) {
7859
7891
  this.ensureInitialized();
7860
- const recipientPubkey = await this.resolveRecipient(recipient);
7861
- const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
7892
+ const resolved = await this.resolveRecipient(recipient);
7893
+ const eventId = await this.deps.transport.sendMessage(resolved.pubkey, content);
7862
7894
  const message = {
7863
7895
  id: eventId,
7864
7896
  senderPubkey: this.deps.identity.chainPubkey,
7865
7897
  senderNametag: this.deps.identity.nametag,
7866
- recipientPubkey,
7898
+ recipientPubkey: resolved.pubkey,
7899
+ ...resolved.nametag ? { recipientNametag: resolved.nametag } : {},
7867
7900
  content,
7868
7901
  timestamp: Date.now(),
7869
7902
  isRead: false
@@ -7981,12 +8014,12 @@ var CommunicationsModule = class {
7981
8014
  */
7982
8015
  async sendComposingIndicator(recipientPubkeyOrNametag) {
7983
8016
  this.ensureInitialized();
7984
- const recipientPubkey = await this.resolveRecipient(recipientPubkeyOrNametag);
8017
+ const resolved = await this.resolveRecipient(recipientPubkeyOrNametag);
7985
8018
  const content = JSON.stringify({
7986
8019
  senderNametag: this.deps.identity.nametag,
7987
8020
  expiresIn: 3e4
7988
8021
  });
7989
- await this.deps.transport.sendComposingIndicator?.(recipientPubkey, content);
8022
+ await this.deps.transport.sendComposingIndicator?.(resolved.pubkey, content);
7990
8023
  }
7991
8024
  /**
7992
8025
  * Subscribe to incoming composing indicators
@@ -8174,13 +8207,14 @@ var CommunicationsModule = class {
8174
8207
  // ===========================================================================
8175
8208
  async resolveRecipient(recipient) {
8176
8209
  if (recipient.startsWith("@")) {
8177
- const pubkey = await this.deps.transport.resolveNametag?.(recipient.slice(1));
8210
+ const nametag = recipient.slice(1);
8211
+ const pubkey = await this.deps.transport.resolveNametag?.(nametag);
8178
8212
  if (!pubkey) {
8179
8213
  throw new Error(`Nametag not found: ${recipient}`);
8180
8214
  }
8181
- return pubkey;
8215
+ return { pubkey, nametag };
8182
8216
  }
8183
- return recipient;
8217
+ return { pubkey: recipient };
8184
8218
  }
8185
8219
  ensureInitialized() {
8186
8220
  if (!this.deps) {
@@ -12861,14 +12895,17 @@ var Sphere = class _Sphere {
12861
12895
  if (!wasConnected) {
12862
12896
  await storage.connect();
12863
12897
  }
12864
- const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12865
- if (mnemonic) return true;
12866
- const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12867
- if (masterKey) return true;
12868
- if (!wasConnected) {
12869
- await storage.disconnect();
12898
+ try {
12899
+ const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12900
+ if (mnemonic) return true;
12901
+ const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12902
+ if (masterKey) return true;
12903
+ return false;
12904
+ } finally {
12905
+ if (!wasConnected) {
12906
+ await storage.disconnect();
12907
+ }
12870
12908
  }
12871
- return false;
12872
12909
  } catch {
12873
12910
  return false;
12874
12911
  }
@@ -13002,6 +13039,9 @@ var Sphere = class _Sphere {
13002
13039
  if (await _Sphere.exists(options.storage)) {
13003
13040
  throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
13004
13041
  }
13042
+ if (!options.storage.isConnected()) {
13043
+ await options.storage.connect();
13044
+ }
13005
13045
  _Sphere.configureTokenRegistry(options.storage, options.network);
13006
13046
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
13007
13047
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -13053,6 +13093,9 @@ var Sphere = class _Sphere {
13053
13093
  marketConfig
13054
13094
  );
13055
13095
  sphere._password = options.password ?? null;
13096
+ if (!options.storage.isConnected()) {
13097
+ await options.storage.connect();
13098
+ }
13056
13099
  await sphere.loadIdentityFromStorage();
13057
13100
  await sphere.initializeProviders();
13058
13101
  await sphere.initializeModules();
@@ -13191,45 +13234,22 @@ var Sphere = class _Sphere {
13191
13234
  await _Sphere.instance.destroy();
13192
13235
  console.log("[Sphere.clear] Sphere instance destroyed");
13193
13236
  }
13237
+ console.log("[Sphere.clear] Clearing L1 vesting cache...");
13194
13238
  await vestingClassifier.destroy();
13195
- if (typeof indexedDB !== "undefined" && typeof indexedDB.databases === "function") {
13196
- console.log("[Sphere.clear] Deleting all sphere IndexedDB databases...");
13197
- try {
13198
- const dbs = await Promise.race([
13199
- indexedDB.databases(),
13200
- new Promise(
13201
- (_, reject) => setTimeout(() => reject(new Error("timeout")), 2e3)
13202
- )
13203
- ]);
13204
- const sphereDbs = dbs.filter((db) => db.name?.startsWith("sphere"));
13205
- if (sphereDbs.length > 0) {
13206
- await Promise.all(sphereDbs.map(
13207
- (db) => new Promise((resolve) => {
13208
- const req = indexedDB.deleteDatabase(db.name);
13209
- req.onsuccess = () => {
13210
- console.log(`[Sphere.clear] Deleted ${db.name}`);
13211
- resolve();
13212
- };
13213
- req.onerror = () => resolve();
13214
- req.onblocked = () => {
13215
- console.warn(`[Sphere.clear] deleteDatabase blocked: ${db.name}`);
13216
- resolve();
13217
- };
13218
- })
13219
- ));
13220
- }
13221
- console.log("[Sphere.clear] IndexedDB cleanup done");
13222
- } catch {
13223
- console.warn("[Sphere.clear] IndexedDB enumeration failed");
13224
- }
13225
- }
13239
+ console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
13240
+ await new Promise((r) => setTimeout(r, 50));
13226
13241
  if (tokenStorage?.clear) {
13242
+ console.log("[Sphere.clear] Clearing token storage...");
13227
13243
  try {
13228
13244
  await tokenStorage.clear();
13245
+ console.log("[Sphere.clear] Token storage cleared");
13229
13246
  } catch (err) {
13230
13247
  console.warn("[Sphere.clear] Token storage clear failed:", err);
13231
13248
  }
13249
+ } else {
13250
+ console.log("[Sphere.clear] No token storage provider to clear");
13232
13251
  }
13252
+ console.log("[Sphere.clear] Clearing KV storage...");
13233
13253
  if (!storage.isConnected()) {
13234
13254
  try {
13235
13255
  await storage.connect();
@@ -13238,7 +13258,11 @@ var Sphere = class _Sphere {
13238
13258
  }
13239
13259
  if (storage.isConnected()) {
13240
13260
  await storage.clear();
13261
+ console.log("[Sphere.clear] KV storage cleared");
13262
+ } else {
13263
+ console.log("[Sphere.clear] KV storage not connected, skipping");
13241
13264
  }
13265
+ console.log("[Sphere.clear] Done");
13242
13266
  }
13243
13267
  /**
13244
13268
  * Get current instance
@@ -14086,8 +14110,12 @@ var Sphere = class _Sphere {
14086
14110
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
14087
14111
  this._storage.setIdentity(this._identity);
14088
14112
  await this._transport.setIdentity(this._identity);
14089
- for (const provider of this._tokenStorageProviders.values()) {
14113
+ console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
14114
+ for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
14115
+ console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
14116
+ await provider.shutdown();
14090
14117
  provider.setIdentity(this._identity);
14118
+ console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
14091
14119
  await provider.initialize();
14092
14120
  }
14093
14121
  await this.reinitializeModulesForNewAddress();
@@ -14169,6 +14197,9 @@ var Sphere = class _Sphere {
14169
14197
  await this._communications.load();
14170
14198
  await this._groupChat?.load();
14171
14199
  await this._market?.load();
14200
+ this._payments.sync().catch((err) => {
14201
+ console.warn("[Sphere] Post-switch sync failed:", err);
14202
+ });
14172
14203
  }
14173
14204
  /**
14174
14205
  * Derive address at a specific index