@unicitylabs/sphere-sdk 0.8.0-dev.2 → 0.8.0-dev.4

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
@@ -7664,6 +7664,10 @@ interface SphereImportOptions {
7664
7664
  derivationMode?: DerivationMode;
7665
7665
  /** Optional nametag to register for this wallet (e.g., 'alice' for @alice). Token is auto-minted. */
7666
7666
  nametag?: string;
7667
+ /** Network this wallet runs on — drives TokenRegistry config. Without it, import
7668
+ * falls back to NETWORKS.testnet and a non-testnet wallet loads the wrong registry
7669
+ * (symbols resolve via baked values but icons/metadata don't) until a reload. */
7670
+ network?: NetworkType;
7667
7671
  /** Storage provider instance */
7668
7672
  storage: StorageProvider;
7669
7673
  /** Optional token storage provider */
@@ -10024,6 +10028,14 @@ declare class TokenRegistry {
10024
10028
  * After initial data is available, start periodic auto-refresh if configured.
10025
10029
  */
10026
10030
  private performInitialLoad;
10031
+ /**
10032
+ * Per-network cache keys. The registry cache MUST be namespaced by remoteUrl:
10033
+ * testnet and testnet2 ship DIFFERENT coinIds for the same symbol, so a single
10034
+ * global key let a stale testnet snapshot be served for a testnet2 request —
10035
+ * wrong/missing icons AND self-mint resolving the wrong-network coinId. Keying
10036
+ * by remoteUrl isolates the snapshots so a network can never read another's.
10037
+ */
10038
+ private cacheKeys;
10027
10039
  /**
10028
10040
  * Load definitions from StorageProvider cache.
10029
10041
  * Only applies if cache exists and is fresh (within refreshIntervalMs).
package/dist/index.d.ts CHANGED
@@ -7664,6 +7664,10 @@ interface SphereImportOptions {
7664
7664
  derivationMode?: DerivationMode;
7665
7665
  /** Optional nametag to register for this wallet (e.g., 'alice' for @alice). Token is auto-minted. */
7666
7666
  nametag?: string;
7667
+ /** Network this wallet runs on — drives TokenRegistry config. Without it, import
7668
+ * falls back to NETWORKS.testnet and a non-testnet wallet loads the wrong registry
7669
+ * (symbols resolve via baked values but icons/metadata don't) until a reload. */
7670
+ network?: NetworkType;
7667
7671
  /** Storage provider instance */
7668
7672
  storage: StorageProvider;
7669
7673
  /** Optional token storage provider */
@@ -10024,6 +10028,14 @@ declare class TokenRegistry {
10024
10028
  * After initial data is available, start periodic auto-refresh if configured.
10025
10029
  */
10026
10030
  private performInitialLoad;
10031
+ /**
10032
+ * Per-network cache keys. The registry cache MUST be namespaced by remoteUrl:
10033
+ * testnet and testnet2 ship DIFFERENT coinIds for the same symbol, so a single
10034
+ * global key let a stale testnet snapshot be served for a testnet2 request —
10035
+ * wrong/missing icons AND self-mint resolving the wrong-network coinId. Keying
10036
+ * by remoteUrl isolates the snapshots so a network can never read another's.
10037
+ */
10038
+ private cacheKeys;
10027
10039
  /**
10028
10040
  * Load definitions from StorageProvider cache.
10029
10041
  * Only applies if cache exists and is fresh (within refreshIntervalMs).
package/dist/index.js CHANGED
@@ -7380,6 +7380,19 @@ var TokenRegistry = class _TokenRegistry {
7380
7380
  // ===========================================================================
7381
7381
  // Cache (StorageProvider)
7382
7382
  // ===========================================================================
7383
+ /**
7384
+ * Per-network cache keys. The registry cache MUST be namespaced by remoteUrl:
7385
+ * testnet and testnet2 ship DIFFERENT coinIds for the same symbol, so a single
7386
+ * global key let a stale testnet snapshot be served for a testnet2 request —
7387
+ * wrong/missing icons AND self-mint resolving the wrong-network coinId. Keying
7388
+ * by remoteUrl isolates the snapshots so a network can never read another's.
7389
+ */
7390
+ cacheKeys() {
7391
+ const base = STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE;
7392
+ const baseTs = STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE_TS;
7393
+ if (!this.remoteUrl) return { data: base, ts: baseTs };
7394
+ return { data: `${base}:${this.remoteUrl}`, ts: `${baseTs}:${this.remoteUrl}` };
7395
+ }
7383
7396
  /**
7384
7397
  * Load definitions from StorageProvider cache.
7385
7398
  * Only applies if cache exists and is fresh (within refreshIntervalMs).
@@ -7387,9 +7400,10 @@ var TokenRegistry = class _TokenRegistry {
7387
7400
  async loadFromCache() {
7388
7401
  if (!this.storage) return false;
7389
7402
  try {
7403
+ const { data: dataKey, ts: tsKey } = this.cacheKeys();
7390
7404
  const [cached, cachedTs] = await Promise.all([
7391
- this.storage.get(STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE),
7392
- this.storage.get(STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE_TS)
7405
+ this.storage.get(dataKey),
7406
+ this.storage.get(tsKey)
7393
7407
  ]);
7394
7408
  if (!cached || !cachedTs) return false;
7395
7409
  const ts = parseInt(cachedTs, 10);
@@ -7412,9 +7426,10 @@ var TokenRegistry = class _TokenRegistry {
7412
7426
  async saveToCache(definitions) {
7413
7427
  if (!this.storage) return;
7414
7428
  try {
7429
+ const { data: dataKey, ts: tsKey } = this.cacheKeys();
7415
7430
  await Promise.all([
7416
- this.storage.set(STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE, JSON.stringify(definitions)),
7417
- this.storage.set(STORAGE_KEYS_GLOBAL.TOKEN_REGISTRY_CACHE_TS, String(Date.now()))
7431
+ this.storage.set(dataKey, JSON.stringify(definitions)),
7432
+ this.storage.set(tsKey, String(Date.now()))
7418
7433
  ]);
7419
7434
  } catch {
7420
7435
  }
@@ -9657,7 +9672,8 @@ var PaymentsModule = class _PaymentsModule {
9657
9672
  try {
9658
9673
  const peerInfo = await this.deps.transport.resolve?.(request.recipient) ?? null;
9659
9674
  const recipientPubkey = this.resolveTransportPubkey(request.recipient, peerInfo);
9660
- const recipientAddress = await this.resolveRecipientAddress(request.recipient, request.addressMode, peerInfo);
9675
+ const willUseEngine = !!(this.deps?.tokenEngine && peerInfo?.chainPubkey);
9676
+ const recipientAddress = willUseEngine ? null : await this.resolveRecipientAddress(request.recipient, request.addressMode, peerInfo);
9661
9677
  const signingService = await this.createSigningService();
9662
9678
  const stClient = this.deps.oracle.getStateTransitionClient?.();
9663
9679
  if (!stClient) {
@@ -9781,6 +9797,7 @@ var PaymentsModule = class _PaymentsModule {
9781
9797
  splitPlan.remainderAmount,
9782
9798
  splitPlan.coinId,
9783
9799
  recipientAddress,
9800
+ // v1 path only — non-null (would have thrown in resolve otherwise)
9784
9801
  onChainMessage
9785
9802
  );
9786
9803
  committedOnChainTokenIds.add(splitPlan.tokenToSplit.uiToken.id);
@@ -9861,6 +9878,7 @@ var PaymentsModule = class _PaymentsModule {
9861
9878
  splitPlan.remainderAmount,
9862
9879
  splitPlan.coinId,
9863
9880
  recipientAddress,
9881
+ // v1 path only — non-null (would have thrown in resolve otherwise)
9864
9882
  {
9865
9883
  memo: request.memo,
9866
9884
  message: onChainMessage,
@@ -12857,7 +12875,7 @@ var PaymentsModule = class _PaymentsModule {
12857
12875
  const nametag = recipient.startsWith("@") ? recipient.slice(1) : info.nametag || recipient;
12858
12876
  if (!info.directAddress) {
12859
12877
  throw new SphereError(
12860
- `"${nametag}" has no DirectAddress \u2014 the recipient must publish a key-based identity binding.`,
12878
+ `"${nametag}" has no published identity \u2014 the recipient must register a Unicity ID (publish a key-based identity binding) before they can receive payments.`,
12861
12879
  "INVALID_RECIPIENT"
12862
12880
  );
12863
12881
  }
@@ -28239,6 +28257,8 @@ var Sphere = class _Sphere {
28239
28257
  const walletExists = await _Sphere.exists(options.storage);
28240
28258
  if (walletExists) {
28241
28259
  const sphere2 = await _Sphere.load({
28260
+ network: options.network,
28261
+ // forward network so load's configureTokenRegistry uses it (not the testnet default)
28242
28262
  storage: options.storage,
28243
28263
  transport: options.transport,
28244
28264
  oracle: options.oracle,
@@ -28273,6 +28293,8 @@ var Sphere = class _Sphere {
28273
28293
  }
28274
28294
  const sphere = await _Sphere.create({
28275
28295
  mnemonic,
28296
+ network: options.network,
28297
+ // forward network so create's configureTokenRegistry uses it (not the testnet default)
28276
28298
  storage: options.storage,
28277
28299
  transport: options.transport,
28278
28300
  oracle: options.oracle,
@@ -28360,6 +28382,12 @@ var Sphere = class _Sphere {
28360
28382
  * This method ensures the main bundle's TokenRegistry is properly configured.
28361
28383
  */
28362
28384
  static configureTokenRegistry(storage, network) {
28385
+ if (!network) {
28386
+ logger.warn(
28387
+ "Sphere",
28388
+ "configureTokenRegistry: no network provided \u2014 defaulting to testnet. Pass options.network to avoid loading the wrong-network registry."
28389
+ );
28390
+ }
28363
28391
  const netConfig = network ? NETWORKS[network] : NETWORKS.testnet;
28364
28392
  TokenRegistry.configure({ remoteUrl: netConfig.tokenRegistryUrl, storage });
28365
28393
  }
@@ -28511,7 +28539,8 @@ var Sphere = class _Sphere {
28511
28539
  await options.storage.connect();
28512
28540
  logger.debug("Sphere", "Storage reconnected");
28513
28541
  }
28514
- const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat);
28542
+ _Sphere.configureTokenRegistry(options.storage, options.network);
28543
+ const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
28515
28544
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
28516
28545
  const accountingConfig = _Sphere.resolveAccountingConfig(options.accounting);
28517
28546
  const swapConfig = _Sphere.resolveSwapConfig(options.swap);