@unicitylabs/sphere-sdk 0.13.2-dev.1 → 0.13.2-dev.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.
@@ -447,8 +447,9 @@ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
447
447
  createForAddress?(sharedClient?: unknown): TokenStorageProvider<TData>;
448
448
  /**
449
449
  * Subscribe to storage events
450
- */
451
- onEvent?(callback: StorageEventCallback): () => void;
450
+
451
+ // --- History operations (optional — not supported by all providers, e.g. IPFS) ---
452
+
452
453
  /** Store a history entry (upsert by dedupKey) */
453
454
  addHistoryEntry?(entry: HistoryRecord): Promise<void>;
454
455
  /** Get all history entries sorted by timestamp descending */
@@ -460,14 +461,6 @@ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
460
461
  /** Bulk import history entries (skip existing dedupKeys). Returns count of newly imported. */
461
462
  importHistoryEntries?(entries: HistoryRecord[]): Promise<number>;
462
463
  }
463
- type StorageEventType = 'storage:saving' | 'storage:saved' | 'storage:loading' | 'storage:loaded' | 'storage:error' | 'storage:remote-updated' | 'sync:started' | 'sync:completed' | 'sync:conflict' | 'sync:error';
464
- interface StorageEvent {
465
- type: StorageEventType;
466
- timestamp: number;
467
- data?: unknown;
468
- error?: string;
469
- }
470
- type StorageEventCallback = (event: StorageEvent) => void;
471
464
  interface TxfStorageDataBase {
472
465
  _meta: TxfMeta;
473
466
  _tombstones?: TxfTombstone[];
@@ -2262,8 +2255,7 @@ declare class PaymentsModule {
2262
2255
  private serverSeenHistoryKeys;
2263
2256
  private incrementalHistoryPulls;
2264
2257
  private hydrationEpoch;
2265
- private storageEventUnsubscribers;
2266
- private syncDebounceTimer;
2258
+ private inventoryDebounceTimer;
2267
2259
  private static readonly SYNC_DEBOUNCE_MS;
2268
2260
  /** Quiet-then-escalate logging for the background wallet-api pumps (#630). */
2269
2261
  private readonly pumpHealth;
@@ -2917,33 +2909,18 @@ declare class PaymentsModule {
2917
2909
  */
2918
2910
  private mintFungibleTokenV2;
2919
2911
  /**
2920
- * Sync local token state with all configured token storage providers (IPFS, file, etc.).
2921
- *
2922
- * For each provider, the local data is packaged into TXF storage format, sent
2923
- * to the provider's `sync()` method, and the merged result is applied locally.
2924
- * Emits `sync:started`, `sync:completed`, and `sync:error` events.
2912
+ * Flush local token state to every configured token storage provider.
2925
2913
  *
2926
- * @returns Summary with counts of tokens added and removed during sync.
2914
+ * Named `sync` for history: it once merged remote TXF state back in, which
2915
+ * only IPFS ever supplied. The remaining providers all implement `sync()` as
2916
+ * "save and return the input unchanged", so this is a write, and the returned
2917
+ * counts are always zero.
2927
2918
  */
2928
2919
  sync(): Promise<{
2929
2920
  added: number;
2930
2921
  removed: number;
2931
2922
  }>;
2932
- private _doSync;
2933
- /**
2934
- * Subscribe to 'storage:remote-updated' events from all token storage providers.
2935
- * When a provider emits this event, a debounced sync is triggered.
2936
- */
2937
- private subscribeToStorageEvents;
2938
- /**
2939
- * Unsubscribe from all storage provider events and clear debounce timer.
2940
- */
2941
- private unsubscribeStorageEvents;
2942
- /**
2943
- * Debounced sync triggered by a storage:remote-updated event.
2944
- * Waits 500ms to batch rapid updates, then performs sync.
2945
- */
2946
- private debouncedSyncFromRemoteUpdate;
2923
+ private _doFlush;
2947
2924
  /**
2948
2925
  * Get all active (non-disabled) token storage providers
2949
2926
  */
@@ -4843,7 +4820,7 @@ interface TrackedAddress extends TrackedAddressEntry {
4843
4820
  /** Primary nametag (from nametag cache, without @ prefix) */
4844
4821
  readonly nametag?: string;
4845
4822
  }
4846
- type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'transfer:delivery_pending' | 'transfer:invalid' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:expired' | 'payment_request:settling' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'composing:started' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'storage:degraded' | 'inventory:conflict' | 'split:checkpoint-stuck' | 'send:partial-remainder' | 'delivery:undeliverable' | 'delivery:deferred' | 'walletapi:session' | 'realtime:status' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection' | 'groupchat:ready' | 'communications:ready' | 'history:updated' | 'invoice:created' | 'invoice:payment' | 'invoice:asset_covered' | 'invoice:target_covered' | 'invoice:covered' | 'invoice:closed' | 'invoice:cancelled' | 'invoice:expired' | 'invoice:unknown_reference' | 'invoice:overpayment' | 'invoice:irrelevant' | 'invoice:auto_returned' | 'invoice:auto_return_failed' | 'invoice:return_received' | 'invoice:over_refund_warning' | 'invoice:receipt_sent' | 'invoice:receipt_received' | 'invoice:cancellation_sent' | 'invoice:cancellation_received' | 'swap:proposal_received' | 'swap:proposed' | 'swap:accepted' | 'swap:rejected' | 'swap:announced' | 'swap:deposit_sent' | 'swap:deposit_confirmed' | 'swap:deposits_covered' | 'swap:concluding' | 'swap:payout_received' | 'swap:completed' | 'swap:cancelled' | 'swap:failed' | 'swap:deposit_returned' | 'swap:bounce_received';
4823
+ type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'transfer:delivery_pending' | 'transfer:invalid' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:expired' | 'payment_request:settling' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'composing:started' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:error' | 'storage:degraded' | 'inventory:conflict' | 'split:checkpoint-stuck' | 'send:partial-remainder' | 'delivery:undeliverable' | 'delivery:deferred' | 'walletapi:session' | 'realtime:status' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection' | 'groupchat:ready' | 'communications:ready' | 'history:updated' | 'invoice:created' | 'invoice:payment' | 'invoice:asset_covered' | 'invoice:target_covered' | 'invoice:covered' | 'invoice:closed' | 'invoice:cancelled' | 'invoice:expired' | 'invoice:unknown_reference' | 'invoice:overpayment' | 'invoice:irrelevant' | 'invoice:auto_returned' | 'invoice:auto_return_failed' | 'invoice:return_received' | 'invoice:over_refund_warning' | 'invoice:receipt_sent' | 'invoice:receipt_received' | 'invoice:cancellation_sent' | 'invoice:cancellation_received' | 'swap:proposal_received' | 'swap:proposed' | 'swap:accepted' | 'swap:rejected' | 'swap:announced' | 'swap:deposit_sent' | 'swap:deposit_confirmed' | 'swap:deposits_covered' | 'swap:concluding' | 'swap:payout_received' | 'swap:completed' | 'swap:cancelled' | 'swap:failed' | 'swap:deposit_returned' | 'swap:bounce_received';
4847
4824
  interface SphereEventMap {
4848
4825
  'transfer:incoming': IncomingTransfer;
4849
4826
  'transfer:confirmed': TransferResult;
@@ -4897,13 +4874,6 @@ interface SphereEventMap {
4897
4874
  source: string;
4898
4875
  count: number;
4899
4876
  };
4900
- 'sync:provider': {
4901
- providerId: string;
4902
- success: boolean;
4903
- added?: number;
4904
- removed?: number;
4905
- error?: string;
4906
- };
4907
4877
  'sync:error': {
4908
4878
  source: string;
4909
4879
  error: string;
@@ -447,8 +447,9 @@ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
447
447
  createForAddress?(sharedClient?: unknown): TokenStorageProvider<TData>;
448
448
  /**
449
449
  * Subscribe to storage events
450
- */
451
- onEvent?(callback: StorageEventCallback): () => void;
450
+
451
+ // --- History operations (optional — not supported by all providers, e.g. IPFS) ---
452
+
452
453
  /** Store a history entry (upsert by dedupKey) */
453
454
  addHistoryEntry?(entry: HistoryRecord): Promise<void>;
454
455
  /** Get all history entries sorted by timestamp descending */
@@ -460,14 +461,6 @@ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
460
461
  /** Bulk import history entries (skip existing dedupKeys). Returns count of newly imported. */
461
462
  importHistoryEntries?(entries: HistoryRecord[]): Promise<number>;
462
463
  }
463
- type StorageEventType = 'storage:saving' | 'storage:saved' | 'storage:loading' | 'storage:loaded' | 'storage:error' | 'storage:remote-updated' | 'sync:started' | 'sync:completed' | 'sync:conflict' | 'sync:error';
464
- interface StorageEvent {
465
- type: StorageEventType;
466
- timestamp: number;
467
- data?: unknown;
468
- error?: string;
469
- }
470
- type StorageEventCallback = (event: StorageEvent) => void;
471
464
  interface TxfStorageDataBase {
472
465
  _meta: TxfMeta;
473
466
  _tombstones?: TxfTombstone[];
@@ -2262,8 +2255,7 @@ declare class PaymentsModule {
2262
2255
  private serverSeenHistoryKeys;
2263
2256
  private incrementalHistoryPulls;
2264
2257
  private hydrationEpoch;
2265
- private storageEventUnsubscribers;
2266
- private syncDebounceTimer;
2258
+ private inventoryDebounceTimer;
2267
2259
  private static readonly SYNC_DEBOUNCE_MS;
2268
2260
  /** Quiet-then-escalate logging for the background wallet-api pumps (#630). */
2269
2261
  private readonly pumpHealth;
@@ -2917,33 +2909,18 @@ declare class PaymentsModule {
2917
2909
  */
2918
2910
  private mintFungibleTokenV2;
2919
2911
  /**
2920
- * Sync local token state with all configured token storage providers (IPFS, file, etc.).
2921
- *
2922
- * For each provider, the local data is packaged into TXF storage format, sent
2923
- * to the provider's `sync()` method, and the merged result is applied locally.
2924
- * Emits `sync:started`, `sync:completed`, and `sync:error` events.
2912
+ * Flush local token state to every configured token storage provider.
2925
2913
  *
2926
- * @returns Summary with counts of tokens added and removed during sync.
2914
+ * Named `sync` for history: it once merged remote TXF state back in, which
2915
+ * only IPFS ever supplied. The remaining providers all implement `sync()` as
2916
+ * "save and return the input unchanged", so this is a write, and the returned
2917
+ * counts are always zero.
2927
2918
  */
2928
2919
  sync(): Promise<{
2929
2920
  added: number;
2930
2921
  removed: number;
2931
2922
  }>;
2932
- private _doSync;
2933
- /**
2934
- * Subscribe to 'storage:remote-updated' events from all token storage providers.
2935
- * When a provider emits this event, a debounced sync is triggered.
2936
- */
2937
- private subscribeToStorageEvents;
2938
- /**
2939
- * Unsubscribe from all storage provider events and clear debounce timer.
2940
- */
2941
- private unsubscribeStorageEvents;
2942
- /**
2943
- * Debounced sync triggered by a storage:remote-updated event.
2944
- * Waits 500ms to batch rapid updates, then performs sync.
2945
- */
2946
- private debouncedSyncFromRemoteUpdate;
2923
+ private _doFlush;
2947
2924
  /**
2948
2925
  * Get all active (non-disabled) token storage providers
2949
2926
  */
@@ -4843,7 +4820,7 @@ interface TrackedAddress extends TrackedAddressEntry {
4843
4820
  /** Primary nametag (from nametag cache, without @ prefix) */
4844
4821
  readonly nametag?: string;
4845
4822
  }
4846
- type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'transfer:delivery_pending' | 'transfer:invalid' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:expired' | 'payment_request:settling' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'composing:started' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'storage:degraded' | 'inventory:conflict' | 'split:checkpoint-stuck' | 'send:partial-remainder' | 'delivery:undeliverable' | 'delivery:deferred' | 'walletapi:session' | 'realtime:status' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection' | 'groupchat:ready' | 'communications:ready' | 'history:updated' | 'invoice:created' | 'invoice:payment' | 'invoice:asset_covered' | 'invoice:target_covered' | 'invoice:covered' | 'invoice:closed' | 'invoice:cancelled' | 'invoice:expired' | 'invoice:unknown_reference' | 'invoice:overpayment' | 'invoice:irrelevant' | 'invoice:auto_returned' | 'invoice:auto_return_failed' | 'invoice:return_received' | 'invoice:over_refund_warning' | 'invoice:receipt_sent' | 'invoice:receipt_received' | 'invoice:cancellation_sent' | 'invoice:cancellation_received' | 'swap:proposal_received' | 'swap:proposed' | 'swap:accepted' | 'swap:rejected' | 'swap:announced' | 'swap:deposit_sent' | 'swap:deposit_confirmed' | 'swap:deposits_covered' | 'swap:concluding' | 'swap:payout_received' | 'swap:completed' | 'swap:cancelled' | 'swap:failed' | 'swap:deposit_returned' | 'swap:bounce_received';
4823
+ type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'transfer:delivery_pending' | 'transfer:invalid' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:expired' | 'payment_request:settling' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'composing:started' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:error' | 'storage:degraded' | 'inventory:conflict' | 'split:checkpoint-stuck' | 'send:partial-remainder' | 'delivery:undeliverable' | 'delivery:deferred' | 'walletapi:session' | 'realtime:status' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection' | 'groupchat:ready' | 'communications:ready' | 'history:updated' | 'invoice:created' | 'invoice:payment' | 'invoice:asset_covered' | 'invoice:target_covered' | 'invoice:covered' | 'invoice:closed' | 'invoice:cancelled' | 'invoice:expired' | 'invoice:unknown_reference' | 'invoice:overpayment' | 'invoice:irrelevant' | 'invoice:auto_returned' | 'invoice:auto_return_failed' | 'invoice:return_received' | 'invoice:over_refund_warning' | 'invoice:receipt_sent' | 'invoice:receipt_received' | 'invoice:cancellation_sent' | 'invoice:cancellation_received' | 'swap:proposal_received' | 'swap:proposed' | 'swap:accepted' | 'swap:rejected' | 'swap:announced' | 'swap:deposit_sent' | 'swap:deposit_confirmed' | 'swap:deposits_covered' | 'swap:concluding' | 'swap:payout_received' | 'swap:completed' | 'swap:cancelled' | 'swap:failed' | 'swap:deposit_returned' | 'swap:bounce_received';
4847
4824
  interface SphereEventMap {
4848
4825
  'transfer:incoming': IncomingTransfer;
4849
4826
  'transfer:confirmed': TransferResult;
@@ -4897,13 +4874,6 @@ interface SphereEventMap {
4897
4874
  source: string;
4898
4875
  count: number;
4899
4876
  };
4900
- 'sync:provider': {
4901
- providerId: string;
4902
- success: boolean;
4903
- added?: number;
4904
- removed?: number;
4905
- error?: string;
4906
- };
4907
4877
  'sync:error': {
4908
4878
  source: string;
4909
4879
  error: string;
@@ -9992,8 +9992,7 @@ var PaymentsModule = class _PaymentsModule {
9992
9992
  incrementalHistoryPulls = 0;
9993
9993
  hydrationEpoch = 0;
9994
9994
  // Storage event subscriptions (push-based sync)
9995
- storageEventUnsubscribers = [];
9996
- syncDebounceTimer = null;
9995
+ inventoryDebounceTimer = null;
9997
9996
  static SYNC_DEBOUNCE_MS = 500;
9998
9997
  /** Quiet-then-escalate logging for the background wallet-api pumps (#630). */
9999
9998
  pumpHealth = new PumpHealth();
@@ -10118,7 +10117,6 @@ var PaymentsModule = class _PaymentsModule {
10118
10117
  assertLegalCustodyComposition(deps);
10119
10118
  this.teardownDeliveryPump();
10120
10119
  this.teardownPaymentRequestPump();
10121
- this.unsubscribeStorageEvents();
10122
10120
  for (const [, resolver] of this.pendingResponseResolvers) {
10123
10121
  clearTimeout(resolver.timeout);
10124
10122
  resolver.reject(new Error("Address switched"));
@@ -10187,7 +10185,6 @@ var PaymentsModule = class _PaymentsModule {
10187
10185
  this.pumpHealth.run("payment-requests", () => this.pumpPaymentRequests());
10188
10186
  }, DELIVERY_POLL_INTERVAL_MS);
10189
10187
  }
10190
- this.subscribeToStorageEvents();
10191
10188
  }
10192
10189
  /**
10193
10190
  * Load all token data from storage providers and restore wallet state.
@@ -10360,7 +10357,6 @@ var PaymentsModule = class _PaymentsModule {
10360
10357
  this.reservationLedger.clear();
10361
10358
  this.parsedTokenCache.clear();
10362
10359
  this.tokens.clear();
10363
- this.unsubscribeStorageEvents();
10364
10360
  }
10365
10361
  // ===========================================================================
10366
10362
  // Public API - Send
@@ -12354,115 +12350,29 @@ var PaymentsModule = class _PaymentsModule {
12354
12350
  // Public API - Sync & Validate
12355
12351
  // ===========================================================================
12356
12352
  /**
12357
- * Sync local token state with all configured token storage providers (IPFS, file, etc.).
12353
+ * Flush local token state to every configured token storage provider.
12358
12354
  *
12359
- * For each provider, the local data is packaged into TXF storage format, sent
12360
- * to the provider's `sync()` method, and the merged result is applied locally.
12361
- * Emits `sync:started`, `sync:completed`, and `sync:error` events.
12362
- *
12363
- * @returns Summary with counts of tokens added and removed during sync.
12355
+ * Named `sync` for history: it once merged remote TXF state back in, which
12356
+ * only IPFS ever supplied. The remaining providers all implement `sync()` as
12357
+ * "save and return the input unchanged", so this is a write, and the returned
12358
+ * counts are always zero.
12364
12359
  */
12365
12360
  async sync() {
12366
12361
  this.ensureInitialized();
12367
- if (this._syncInProgress) {
12368
- return this._syncInProgress;
12369
- }
12370
- this._syncInProgress = this._doSync();
12362
+ if (this._syncInProgress) return this._syncInProgress;
12363
+ this._syncInProgress = this._doFlush();
12371
12364
  try {
12372
12365
  return await this._syncInProgress;
12373
12366
  } finally {
12374
12367
  this._syncInProgress = null;
12375
12368
  }
12376
12369
  }
12377
- async _doSync() {
12370
+ async _doFlush() {
12378
12371
  this.deps.emitEvent("sync:started", { source: "payments" });
12379
12372
  try {
12380
- const providers = this.getTokenStorageProviders();
12381
- if (providers.size === 0) {
12382
- await this.save();
12383
- this.deps.emitEvent("sync:completed", {
12384
- source: "payments",
12385
- count: this.tokens.size
12386
- });
12387
- return { added: 0, removed: 0 };
12388
- }
12389
- const localData = await this.createStorageData();
12390
- let totalAdded = 0;
12391
- let totalRemoved = 0;
12392
- const savedNametags = [...this.nametags];
12393
- for (const [providerId, provider] of providers) {
12394
- try {
12395
- const result = await provider.sync(localData);
12396
- if (result.success && result.merged) {
12397
- const mergedMeta = result.merged?._meta;
12398
- const currentChain = this.deps.identity.chainPubkey;
12399
- const isLegacyAlpha = mergedMeta?.address?.startsWith("alpha1") ?? false;
12400
- if (mergedMeta?.address && currentChain && !isLegacyAlpha && mergedMeta.address !== currentChain) {
12401
- logger.warn("Payments", `Sync: rejecting data from provider ${providerId} \u2014 address mismatch (got=${mergedMeta.address.slice(0, 20)}... expected=${currentChain.slice(0, 20)}...)`);
12402
- continue;
12403
- }
12404
- const savedTokens = new Map(this.tokens);
12405
- this.loadFromStorageData(result.merged);
12406
- const existingGenesisIds = /* @__PURE__ */ new Set();
12407
- for (const existing of this.tokens.values()) {
12408
- const gid = extractTokenIdFromSdkData(existing.sdkData);
12409
- if (gid) existingGenesisIds.add(gid);
12410
- }
12411
- let restoredCount = 0;
12412
- for (const [tokenId, token] of savedTokens) {
12413
- if (this.tokens.has(tokenId)) continue;
12414
- const sdkTokenId = extractTokenIdFromSdkData(token.sdkData);
12415
- const stateHash = extractStateHashFromSdkData(token.sdkData);
12416
- if (sdkTokenId && stateHash && this.isStateTombstoned(sdkTokenId, stateHash)) {
12417
- continue;
12418
- }
12419
- if (sdkTokenId && existingGenesisIds.has(sdkTokenId)) {
12420
- continue;
12421
- }
12422
- this.tokens.set(tokenId, token);
12423
- if (sdkTokenId) existingGenesisIds.add(sdkTokenId);
12424
- restoredCount++;
12425
- }
12426
- if (restoredCount > 0) {
12427
- logger.debug("Payments", `Sync: restored ${restoredCount} token(s) lost by loadFromStorageData`);
12428
- }
12429
- if (this.nametags.length === 0 && savedNametags.length > 0) {
12430
- this.nametags = savedNametags;
12431
- }
12432
- await this.rebuildParsedTokenCache();
12433
- const txfData = result.merged;
12434
- if (txfData._history && txfData._history.length > 0) {
12435
- const imported = await this.importRemoteHistoryEntries(txfData._history);
12436
- if (imported > 0) {
12437
- logger.debug("Payments", `Imported ${imported} history entries from IPFS sync`);
12438
- }
12439
- }
12440
- totalAdded += result.added;
12441
- totalRemoved += result.removed;
12442
- }
12443
- this.deps.emitEvent("sync:provider", {
12444
- providerId,
12445
- success: result.success,
12446
- added: result.added,
12447
- removed: result.removed
12448
- });
12449
- } catch (providerError) {
12450
- logger.warn("Payments", `Sync failed for provider ${providerId}:`, providerError);
12451
- this.deps.emitEvent("sync:provider", {
12452
- providerId,
12453
- success: false,
12454
- error: providerError instanceof Error ? providerError.message : String(providerError)
12455
- });
12456
- }
12457
- }
12458
- if (totalAdded > 0 || totalRemoved > 0) {
12459
- await this.save();
12460
- }
12461
- this.deps.emitEvent("sync:completed", {
12462
- source: "payments",
12463
- count: this.tokens.size
12464
- });
12465
- return { added: totalAdded, removed: totalRemoved };
12373
+ await this.save();
12374
+ this.deps.emitEvent("sync:completed", { source: "payments", count: this.tokens.size });
12375
+ return { added: 0, removed: 0 };
12466
12376
  } catch (error) {
12467
12377
  this.deps.emitEvent("sync:error", {
12468
12378
  source: "payments",
@@ -12471,66 +12381,6 @@ var PaymentsModule = class _PaymentsModule {
12471
12381
  throw error;
12472
12382
  }
12473
12383
  }
12474
- // ===========================================================================
12475
- // Storage Event Subscription (Push-Based Sync)
12476
- // ===========================================================================
12477
- /**
12478
- * Subscribe to 'storage:remote-updated' events from all token storage providers.
12479
- * When a provider emits this event, a debounced sync is triggered.
12480
- */
12481
- subscribeToStorageEvents() {
12482
- this.unsubscribeStorageEvents();
12483
- const providers = this.getTokenStorageProviders();
12484
- for (const [providerId, provider] of providers) {
12485
- if (provider.onEvent) {
12486
- const unsub = provider.onEvent((event) => {
12487
- if (event.type === "storage:remote-updated") {
12488
- logger.debug("Payments", "Remote update detected from provider", providerId, event.data);
12489
- this.debouncedSyncFromRemoteUpdate(providerId, event.data);
12490
- }
12491
- });
12492
- this.storageEventUnsubscribers.push(unsub);
12493
- }
12494
- }
12495
- }
12496
- /**
12497
- * Unsubscribe from all storage provider events and clear debounce timer.
12498
- */
12499
- unsubscribeStorageEvents() {
12500
- for (const unsub of this.storageEventUnsubscribers) {
12501
- unsub();
12502
- }
12503
- this.storageEventUnsubscribers = [];
12504
- if (this.syncDebounceTimer) {
12505
- clearTimeout(this.syncDebounceTimer);
12506
- this.syncDebounceTimer = null;
12507
- }
12508
- }
12509
- /**
12510
- * Debounced sync triggered by a storage:remote-updated event.
12511
- * Waits 500ms to batch rapid updates, then performs sync.
12512
- */
12513
- debouncedSyncFromRemoteUpdate(providerId, eventData) {
12514
- if (this.syncDebounceTimer) {
12515
- clearTimeout(this.syncDebounceTimer);
12516
- }
12517
- this.syncDebounceTimer = setTimeout(() => {
12518
- this.syncDebounceTimer = null;
12519
- this.sync().then((result) => {
12520
- const data = eventData;
12521
- this.deps?.emitEvent("sync:remote-update", {
12522
- providerId,
12523
- name: data?.name ?? "",
12524
- sequence: data?.sequence ?? 0,
12525
- cid: data?.cid ?? "",
12526
- added: result.added,
12527
- removed: result.removed
12528
- });
12529
- }).catch((err) => {
12530
- logger.debug("Payments", "Auto-sync from remote update failed:", err);
12531
- });
12532
- }, _PaymentsModule.SYNC_DEBOUNCE_MS);
12533
- }
12534
12384
  /**
12535
12385
  * Get all active (non-disabled) token storage providers
12536
12386
  */
@@ -12575,7 +12425,6 @@ var PaymentsModule = class _PaymentsModule {
12575
12425
  updateTokenStorageProviders(providers) {
12576
12426
  if (this.deps) {
12577
12427
  this.deps.tokenStorageProviders = providers;
12578
- this.subscribeToStorageEvents();
12579
12428
  }
12580
12429
  }
12581
12430
  /**
@@ -12737,6 +12586,10 @@ var PaymentsModule = class _PaymentsModule {
12737
12586
  teardownDeliveryPump() {
12738
12587
  this.deliveryWakeUnsub?.();
12739
12588
  this.deliveryWakeUnsub = null;
12589
+ if (this.inventoryDebounceTimer !== null) {
12590
+ clearTimeout(this.inventoryDebounceTimer);
12591
+ this.inventoryDebounceTimer = null;
12592
+ }
12740
12593
  if (this.deliveryPollTimer !== null) {
12741
12594
  clearInterval(this.deliveryPollTimer);
12742
12595
  this.deliveryPollTimer = null;
@@ -12776,11 +12629,11 @@ var PaymentsModule = class _PaymentsModule {
12776
12629
  * without waiting for the next poll tick.
12777
12630
  */
12778
12631
  debouncedInventorySyncFromWake() {
12779
- if (this.syncDebounceTimer) {
12780
- clearTimeout(this.syncDebounceTimer);
12632
+ if (this.inventoryDebounceTimer) {
12633
+ clearTimeout(this.inventoryDebounceTimer);
12781
12634
  }
12782
- this.syncDebounceTimer = setTimeout(() => {
12783
- this.syncDebounceTimer = null;
12635
+ this.inventoryDebounceTimer = setTimeout(() => {
12636
+ this.inventoryDebounceTimer = null;
12784
12637
  this.pumpHealth.run("inventory", () => this.resyncInventory(true));
12785
12638
  }, _PaymentsModule.SYNC_DEBOUNCE_MS);
12786
12639
  }
@@ -28928,16 +28781,6 @@ var Sphere = class _Sphere {
28928
28781
  });
28929
28782
  if (unsub) this._providerEventCleanups.push(unsub);
28930
28783
  }
28931
- for (const [providerId, provider] of this._tokenStorageProviders) {
28932
- if (typeof provider.onEvent === "function") {
28933
- const unsub = provider.onEvent((event) => {
28934
- if (event.type === "storage:error" || event.type === "sync:error") {
28935
- this.emitConnectionChanged(providerId, provider.isConnected(), provider.getStatus(), event.error);
28936
- }
28937
- });
28938
- if (unsub) this._providerEventCleanups.push(unsub);
28939
- }
28940
- }
28941
28784
  }
28942
28785
  /**
28943
28786
  * Emit connection:changed with deduplication — only emits if status actually changed.