@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.
@@ -6374,6 +6374,29 @@ var PaymentsModule = class _PaymentsModule {
6374
6374
  this.nametags = [];
6375
6375
  await this.save();
6376
6376
  }
6377
+ /**
6378
+ * Reload nametag data from storage providers into memory.
6379
+ *
6380
+ * Used as a recovery mechanism when `this.nametags` is unexpectedly empty
6381
+ * (e.g., wiped by sync or race condition) but nametag data exists in storage.
6382
+ */
6383
+ async reloadNametagsFromStorage() {
6384
+ const providers = this.getTokenStorageProviders();
6385
+ for (const [, provider] of providers) {
6386
+ try {
6387
+ const result = await provider.load();
6388
+ if (result.success && result.data) {
6389
+ const parsed = parseTxfStorageData(result.data);
6390
+ if (parsed.nametags.length > 0) {
6391
+ this.nametags = parsed.nametags;
6392
+ this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
6393
+ return;
6394
+ }
6395
+ }
6396
+ } catch {
6397
+ }
6398
+ }
6399
+ }
6377
6400
  /**
6378
6401
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
6379
6402
  * This creates the nametag token required for receiving tokens via PROXY addresses
@@ -6498,11 +6521,15 @@ var PaymentsModule = class _PaymentsModule {
6498
6521
  const localData = await this.createStorageData();
6499
6522
  let totalAdded = 0;
6500
6523
  let totalRemoved = 0;
6524
+ const savedNametags = [...this.nametags];
6501
6525
  for (const [providerId, provider] of providers) {
6502
6526
  try {
6503
6527
  const result = await provider.sync(localData);
6504
6528
  if (result.success && result.merged) {
6505
6529
  this.loadFromStorageData(result.merged);
6530
+ if (this.nametags.length === 0 && savedNametags.length > 0) {
6531
+ this.nametags = savedNametags;
6532
+ }
6506
6533
  totalAdded += result.added;
6507
6534
  totalRemoved += result.removed;
6508
6535
  }
@@ -6890,7 +6917,12 @@ var PaymentsModule = class _PaymentsModule {
6890
6917
  let nametagTokens = [];
6891
6918
  if (addressScheme === import_AddressScheme.AddressScheme.PROXY) {
6892
6919
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
6893
- const proxyNametag = this.getNametag();
6920
+ let proxyNametag = this.getNametag();
6921
+ if (!proxyNametag?.token) {
6922
+ this.log("Nametag missing in memory, attempting reload from storage...");
6923
+ await this.reloadNametagsFromStorage();
6924
+ proxyNametag = this.getNametag();
6925
+ }
6894
6926
  if (!proxyNametag?.token) {
6895
6927
  throw new Error("Cannot finalize PROXY transfer - no nametag token");
6896
6928
  }
@@ -7495,13 +7527,14 @@ var CommunicationsModule = class {
7495
7527
  */
7496
7528
  async sendDM(recipient, content) {
7497
7529
  this.ensureInitialized();
7498
- const recipientPubkey = await this.resolveRecipient(recipient);
7499
- const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
7530
+ const resolved = await this.resolveRecipient(recipient);
7531
+ const eventId = await this.deps.transport.sendMessage(resolved.pubkey, content);
7500
7532
  const message = {
7501
7533
  id: eventId,
7502
7534
  senderPubkey: this.deps.identity.chainPubkey,
7503
7535
  senderNametag: this.deps.identity.nametag,
7504
- recipientPubkey,
7536
+ recipientPubkey: resolved.pubkey,
7537
+ ...resolved.nametag ? { recipientNametag: resolved.nametag } : {},
7505
7538
  content,
7506
7539
  timestamp: Date.now(),
7507
7540
  isRead: false
@@ -7619,12 +7652,12 @@ var CommunicationsModule = class {
7619
7652
  */
7620
7653
  async sendComposingIndicator(recipientPubkeyOrNametag) {
7621
7654
  this.ensureInitialized();
7622
- const recipientPubkey = await this.resolveRecipient(recipientPubkeyOrNametag);
7655
+ const resolved = await this.resolveRecipient(recipientPubkeyOrNametag);
7623
7656
  const content = JSON.stringify({
7624
7657
  senderNametag: this.deps.identity.nametag,
7625
7658
  expiresIn: 3e4
7626
7659
  });
7627
- await this.deps.transport.sendComposingIndicator?.(recipientPubkey, content);
7660
+ await this.deps.transport.sendComposingIndicator?.(resolved.pubkey, content);
7628
7661
  }
7629
7662
  /**
7630
7663
  * Subscribe to incoming composing indicators
@@ -7812,13 +7845,14 @@ var CommunicationsModule = class {
7812
7845
  // ===========================================================================
7813
7846
  async resolveRecipient(recipient) {
7814
7847
  if (recipient.startsWith("@")) {
7815
- const pubkey = await this.deps.transport.resolveNametag?.(recipient.slice(1));
7848
+ const nametag = recipient.slice(1);
7849
+ const pubkey = await this.deps.transport.resolveNametag?.(nametag);
7816
7850
  if (!pubkey) {
7817
7851
  throw new Error(`Nametag not found: ${recipient}`);
7818
7852
  }
7819
- return pubkey;
7853
+ return { pubkey, nametag };
7820
7854
  }
7821
- return recipient;
7855
+ return { pubkey: recipient };
7822
7856
  }
7823
7857
  ensureInitialized() {
7824
7858
  if (!this.deps) {
@@ -12584,14 +12618,17 @@ var Sphere = class _Sphere {
12584
12618
  if (!wasConnected) {
12585
12619
  await storage.connect();
12586
12620
  }
12587
- const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12588
- if (mnemonic) return true;
12589
- const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12590
- if (masterKey) return true;
12591
- if (!wasConnected) {
12592
- await storage.disconnect();
12621
+ try {
12622
+ const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
12623
+ if (mnemonic) return true;
12624
+ const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
12625
+ if (masterKey) return true;
12626
+ return false;
12627
+ } finally {
12628
+ if (!wasConnected) {
12629
+ await storage.disconnect();
12630
+ }
12593
12631
  }
12594
- return false;
12595
12632
  } catch {
12596
12633
  return false;
12597
12634
  }
@@ -12725,6 +12762,9 @@ var Sphere = class _Sphere {
12725
12762
  if (await _Sphere.exists(options.storage)) {
12726
12763
  throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
12727
12764
  }
12765
+ if (!options.storage.isConnected()) {
12766
+ await options.storage.connect();
12767
+ }
12728
12768
  _Sphere.configureTokenRegistry(options.storage, options.network);
12729
12769
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
12730
12770
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -12776,6 +12816,9 @@ var Sphere = class _Sphere {
12776
12816
  marketConfig
12777
12817
  );
12778
12818
  sphere._password = options.password ?? null;
12819
+ if (!options.storage.isConnected()) {
12820
+ await options.storage.connect();
12821
+ }
12779
12822
  await sphere.loadIdentityFromStorage();
12780
12823
  await sphere.initializeProviders();
12781
12824
  await sphere.initializeModules();
@@ -12914,45 +12957,22 @@ var Sphere = class _Sphere {
12914
12957
  await _Sphere.instance.destroy();
12915
12958
  console.log("[Sphere.clear] Sphere instance destroyed");
12916
12959
  }
12960
+ console.log("[Sphere.clear] Clearing L1 vesting cache...");
12917
12961
  await vestingClassifier.destroy();
12918
- if (typeof indexedDB !== "undefined" && typeof indexedDB.databases === "function") {
12919
- console.log("[Sphere.clear] Deleting all sphere IndexedDB databases...");
12920
- try {
12921
- const dbs = await Promise.race([
12922
- indexedDB.databases(),
12923
- new Promise(
12924
- (_, reject) => setTimeout(() => reject(new Error("timeout")), 2e3)
12925
- )
12926
- ]);
12927
- const sphereDbs = dbs.filter((db) => db.name?.startsWith("sphere"));
12928
- if (sphereDbs.length > 0) {
12929
- await Promise.all(sphereDbs.map(
12930
- (db) => new Promise((resolve) => {
12931
- const req = indexedDB.deleteDatabase(db.name);
12932
- req.onsuccess = () => {
12933
- console.log(`[Sphere.clear] Deleted ${db.name}`);
12934
- resolve();
12935
- };
12936
- req.onerror = () => resolve();
12937
- req.onblocked = () => {
12938
- console.warn(`[Sphere.clear] deleteDatabase blocked: ${db.name}`);
12939
- resolve();
12940
- };
12941
- })
12942
- ));
12943
- }
12944
- console.log("[Sphere.clear] IndexedDB cleanup done");
12945
- } catch {
12946
- console.warn("[Sphere.clear] IndexedDB enumeration failed");
12947
- }
12948
- }
12962
+ console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
12963
+ await new Promise((r) => setTimeout(r, 50));
12949
12964
  if (tokenStorage?.clear) {
12965
+ console.log("[Sphere.clear] Clearing token storage...");
12950
12966
  try {
12951
12967
  await tokenStorage.clear();
12968
+ console.log("[Sphere.clear] Token storage cleared");
12952
12969
  } catch (err) {
12953
12970
  console.warn("[Sphere.clear] Token storage clear failed:", err);
12954
12971
  }
12972
+ } else {
12973
+ console.log("[Sphere.clear] No token storage provider to clear");
12955
12974
  }
12975
+ console.log("[Sphere.clear] Clearing KV storage...");
12956
12976
  if (!storage.isConnected()) {
12957
12977
  try {
12958
12978
  await storage.connect();
@@ -12961,7 +12981,11 @@ var Sphere = class _Sphere {
12961
12981
  }
12962
12982
  if (storage.isConnected()) {
12963
12983
  await storage.clear();
12984
+ console.log("[Sphere.clear] KV storage cleared");
12985
+ } else {
12986
+ console.log("[Sphere.clear] KV storage not connected, skipping");
12964
12987
  }
12988
+ console.log("[Sphere.clear] Done");
12965
12989
  }
12966
12990
  /**
12967
12991
  * Get current instance
@@ -13809,8 +13833,12 @@ var Sphere = class _Sphere {
13809
13833
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
13810
13834
  this._storage.setIdentity(this._identity);
13811
13835
  await this._transport.setIdentity(this._identity);
13812
- for (const provider of this._tokenStorageProviders.values()) {
13836
+ console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
13837
+ for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
13838
+ console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
13839
+ await provider.shutdown();
13813
13840
  provider.setIdentity(this._identity);
13841
+ console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
13814
13842
  await provider.initialize();
13815
13843
  }
13816
13844
  await this.reinitializeModulesForNewAddress();
@@ -13892,6 +13920,9 @@ var Sphere = class _Sphere {
13892
13920
  await this._communications.load();
13893
13921
  await this._groupChat?.load();
13894
13922
  await this._market?.load();
13923
+ this._payments.sync().catch((err) => {
13924
+ console.warn("[Sphere] Post-switch sync failed:", err);
13925
+ });
13895
13926
  }
13896
13927
  /**
13897
13928
  * Derive address at a specific index