@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.
- package/README.md +1 -11
- package/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +20 -177
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +11 -41
- package/dist/core/index.d.ts +11 -41
- package/dist/core/index.js +20 -177
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.d.cts +3 -10
- package/dist/impl/nodejs/index.d.ts +3 -10
- package/dist/impl/shared/wallet-api/index.d.cts +3 -10
- package/dist/impl/shared/wallet-api/index.d.ts +3 -10
- package/dist/index.cjs +20 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -33
- package/dist/index.d.ts +11 -33
- package/dist/index.js +20 -177
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.d.cts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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:
|
|
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;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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:
|
|
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;
|
package/dist/core/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
*
|
|
12353
|
+
* Flush local token state to every configured token storage provider.
|
|
12358
12354
|
*
|
|
12359
|
-
*
|
|
12360
|
-
*
|
|
12361
|
-
*
|
|
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
|
-
|
|
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
|
|
12370
|
+
async _doFlush() {
|
|
12378
12371
|
this.deps.emitEvent("sync:started", { source: "payments" });
|
|
12379
12372
|
try {
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
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.
|
|
12780
|
-
clearTimeout(this.
|
|
12632
|
+
if (this.inventoryDebounceTimer) {
|
|
12633
|
+
clearTimeout(this.inventoryDebounceTimer);
|
|
12781
12634
|
}
|
|
12782
|
-
this.
|
|
12783
|
-
this.
|
|
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.
|