@glyphteck/veyl 0.74.1 → 0.75.0

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/account.js CHANGED
@@ -16784,13 +16784,13 @@ var RECENT_PEER_REFRESH_THROTTLE_MS = 120;
16784
16784
  var BAN_REFRESH_GRACE_MS = 50;
16785
16785
  var REQUEST_MONEY_MAX_SATS = SATS_PER_BITCOIN * 100000n;
16786
16786
  var WALLET_TRANSFER_POLL_MS = 3 * MS_PER_SECOND;
16787
- var WALLET_ACTIVE_TRANSFER_REFRESH_MS = MS_PER_SECOND;
16787
+ var WALLET_TRANSFER_REPAIR_MS = 30 * MS_PER_SECOND;
16788
16788
  var WALLET_CACHE_HYDRATE_DELAY_MS = 0;
16789
16789
  var WALLET_BOOT_REFRESH_DELAY_MS = 500;
16790
16790
  var WALLET_BOOT_CACHED_REFRESH_DELAY_MS = 2500;
16791
16791
  var WALLET_REGTEST_DEPOSIT_CLAIM_POLL_MS = 20 * MS_PER_SECOND;
16792
16792
  var WALLET_MAINNET_DEPOSIT_CLAIM_POLL_MS = MINUTE_MS;
16793
- var WALLET_BALANCE_EVENT_COALESCE_MS = 2 * MS_PER_SECOND;
16793
+ var WALLET_BALANCE_EVENT_COALESCE_MS = 100;
16794
16794
  var WALLET_INCOMING_UPDATE_COALESCE_MS = 250;
16795
16795
  var WALLET_AUTO_CLAIM_MAX_FEE_SATS = 5000;
16796
16796
  var WALLET_CLAIM_PAGE_SIZE = 100;
@@ -54549,56 +54549,25 @@ function createIncomingTransferClaims({ wallet, claim, batchSize = null, getTran
54549
54549
  }
54550
54550
  });
54551
54551
  }
54552
- async function queryPendingTransferIds(wallet, ids = [], diag) {
54553
- if (!ids.length || typeof wallet?.transferService?.queryPendingTransfers !== "function") {
54554
- return new Set;
54555
- }
54556
- const startedAt = Date.now();
54557
- markDiag(diag, "wallet.pendingTxs.claim.verify.start", { count: ids.length });
54558
- const requestedIds = new Set(ids);
54559
- try {
54560
- const page = await wallet.transferService.queryPendingTransfers.call(wallet.transferService, ids);
54561
- const pendingTransfers = (Array.isArray(page?.transfers) ? page.transfers : []).filter((transfer) => requestedIds.has(String(transfer?.id || "")));
54562
- markDone(diag, "wallet.pendingTxs.claim.verify", startedAt, { count: ids.length, pending: pendingTransfers.length });
54563
- return new Set(pendingTransfers.map((transfer) => String(transfer?.id || "")).filter(Boolean));
54564
- } catch (error) {
54565
- markError(diag, "wallet.pendingTxs.claim.verify", startedAt, error, { count: ids.length });
54566
- throw error;
54567
- }
54568
- }
54569
- async function claimIncomingTransfersById(wallet, transfers = [], { onClaimed, emitClaimEvents = false, drainAll = true, diag } = {}) {
54552
+ async function claimIncomingTransfersById(wallet, transfers = [], { onClaimed, emitClaimEvents = false, diag } = {}) {
54570
54553
  const ids = transferIds(transfers);
54571
- if (!ids.length || typeof wallet?.transferService?.queryPendingTransfers !== "function" || typeof wallet?.claimTransfers !== "function" && typeof wallet?.claimTransfer !== "function") {
54554
+ if (!ids.length || typeof wallet?.transferService?.queryPendingTransfers !== "function" || typeof wallet?.claimTransfer !== "function") {
54572
54555
  return [];
54573
54556
  }
54574
54557
  const requestedIds = new Set(ids);
54575
54558
  const activeClaim = activeWalletClaims.get(wallet);
54576
54559
  if (activeClaim) {
54577
- const claimedIds = transferIds(await activeClaim).filter((id) => requestedIds.has(id));
54560
+ const claimedIds = transferIds(await activeClaim.catch(() => [])).filter((id) => requestedIds.has(id));
54578
54561
  if (claimedIds.length) {
54579
54562
  onClaimed?.(claimedIds);
54580
54563
  }
54581
- return claimedIds;
54564
+ const remaining = ids.filter((id) => !claimedIds.includes(id));
54565
+ if (!remaining.length)
54566
+ return claimedIds;
54567
+ const next = await claimIncomingTransfersById(wallet, remaining, { onClaimed, emitClaimEvents, diag });
54568
+ return [...claimedIds, ...next];
54582
54569
  }
54583
54570
  const claimPromise = (async () => {
54584
- if (drainAll !== false && typeof wallet?.claimTransfers === "function") {
54585
- const claimedIds2 = [];
54586
- const claimStartedAt = Date.now();
54587
- markDiag(diag, "wallet.pendingTxs.claim.sdk.start", { count: ids.length, mode: "all" });
54588
- try {
54589
- claimedIds2.push(...transferIds(await wallet.claimTransfers(undefined, emitClaimEvents === true)));
54590
- markDone(diag, "wallet.pendingTxs.claim.sdk", claimStartedAt, { count: ids.length, mode: "all", claimed: claimedIds2.length });
54591
- } catch (error) {
54592
- markError(diag, "wallet.pendingTxs.claim.sdk", claimStartedAt, error, { count: ids.length, mode: "all" });
54593
- }
54594
- const pendingIds2 = await queryPendingTransferIds(wallet, ids, diag).catch(() => new Set);
54595
- claimedIds2.push(...ids.filter((id) => !pendingIds2.has(id)));
54596
- const uniqueClaimedIds = [...new Set(claimedIds2)];
54597
- if (uniqueClaimedIds.length) {
54598
- onClaimed?.(uniqueClaimedIds);
54599
- }
54600
- return uniqueClaimedIds;
54601
- }
54602
54571
  const queryStartedAt = Date.now();
54603
54572
  markDiag(diag, "wallet.pendingTxs.claim.query.start", { count: ids.length });
54604
54573
  let page;
@@ -54610,13 +54579,7 @@ async function claimIncomingTransfersById(wallet, transfers = [], { onClaimed, e
54610
54579
  }
54611
54580
  const pendingTransfers = (Array.isArray(page?.transfers) ? page.transfers : []).filter((transfer) => requestedIds.has(String(transfer?.id || "")));
54612
54581
  markDone(diag, "wallet.pendingTxs.claim.query", queryStartedAt, { count: ids.length, pending: pendingTransfers.length });
54613
- const pendingIds = new Set(pendingTransfers.map((transfer) => String(transfer?.id || "")).filter(Boolean));
54614
54582
  const claimedIds = [];
54615
- const alreadySettledIds = ids.filter((id) => !pendingIds.has(id));
54616
- if (alreadySettledIds.length) {
54617
- claimedIds.push(...alreadySettledIds);
54618
- onClaimed?.(alreadySettledIds);
54619
- }
54620
54583
  for (const transfer of pendingTransfers) {
54621
54584
  if (!isClaimablePendingTransfer(transfer)) {
54622
54585
  continue;
@@ -54896,7 +54859,7 @@ async function claimStaticDeposits(wallet, { maxFeeSats = AUTO_CLAIM_MAX_FEE_SAT
54896
54859
  }
54897
54860
 
54898
54861
  // ../../core/wallet/claims.js
54899
- function createDepositClaims({ wallet, updateWalletData, diag }) {
54862
+ function createDepositClaims({ wallet, diag }) {
54900
54863
  let claimPromise = null;
54901
54864
  let closed = false;
54902
54865
  const claimDeposits = async () => {
@@ -54922,27 +54885,8 @@ function createDepositClaims({ wallet, updateWalletData, diag }) {
54922
54885
  claimPromise = request;
54923
54886
  return request;
54924
54887
  };
54925
- const refresh = async () => {
54926
- const startedAt = Date.now();
54927
- markDiag(diag, "wallet.refresh.start", {});
54928
- const claimed = await claimDeposits();
54929
- if (!closed) {
54930
- await updateWalletData({ force: true, reason: "deposit-refresh" });
54931
- }
54932
- markDone(diag, "wallet.refresh", startedAt, { claimed: !!claimed });
54933
- };
54934
- const refreshClaims = async () => {
54935
- const claimed = await claimDeposits();
54936
- if (!claimed || closed) {
54937
- return false;
54938
- }
54939
- await updateWalletData({ force: true, reason: "deposit-claim" });
54940
- return true;
54941
- };
54942
54888
  return {
54943
54889
  claimDeposits,
54944
- refresh,
54945
- refreshClaims,
54946
54890
  close() {
54947
54891
  closed = true;
54948
54892
  claimPromise = null;
@@ -55087,7 +55031,6 @@ function createLightning({ wallet }) {
55087
55031
 
55088
55032
  // ../../core/wallet/lifecycle.js
55089
55033
  var POLL_TXS_RATE = WALLET_TRANSFER_POLL_MS;
55090
- var ACTIVE_TRANSFER_REFRESH_RATE = WALLET_ACTIVE_TRANSFER_REFRESH_MS;
55091
55034
  var BOOT_REFRESH_DELAY_MS = WALLET_BOOT_REFRESH_DELAY_MS;
55092
55035
  var BOOT_CACHED_REFRESH_DELAY_MS = WALLET_BOOT_CACHED_REFRESH_DELAY_MS;
55093
55036
  var BOOT_CACHE_DECISION_DELAY_MS = BOOT_REFRESH_DELAY_MS + Math.max(0, WALLET_CACHE_HYDRATE_DELAY_MS) + 250;
@@ -55161,7 +55104,7 @@ function createWalletData({ wallet, getBalance, getRecentTxs, diag }) {
55161
55104
  tasks.push(getBalance());
55162
55105
  }
55163
55106
  if (currentRequest.transfers) {
55164
- tasks.push(getRecentTxs({ force: currentRequest.force, reason: currentRequest.reason }));
55107
+ tasks.push(getRecentTxs({ force: currentRequest.force, reason: currentRequest.reason, includePending: false }));
55165
55108
  }
55166
55109
  await Promise.all(tasks);
55167
55110
  markDone(diag, "wallet.update", startedAt, {
@@ -55196,353 +55139,240 @@ function createWalletData({ wallet, getBalance, getRecentTxs, diag }) {
55196
55139
  };
55197
55140
  return updateWalletData;
55198
55141
  }
55199
- function createWalletEvents({ wallet, updateWalletData, getTransferState, setBalance, setTokenBalances, setSatsBalanceResult, diag }) {
55200
- const balanceEvent = { timer: null, value: null };
55201
- const incomingEvent = { timer: null, balance: null };
55202
- const claimedEvent = { timer: null, balance: null, transfers: [], ids: [] };
55203
- if (!wallet || typeof wallet.on !== "function" || typeof wallet.off !== "function") {
55204
- return { close() {} };
55205
- }
55206
- const flushBalanceEvent = () => {
55207
- balanceEvent.timer = null;
55208
- const value = balanceEvent.value;
55209
- balanceEvent.value = null;
55210
- if (value) {
55211
- if (getTransferState().hasActivePendingClaim?.() === true) {
55212
- return;
55213
- }
55214
- markDiag(diag, "wallet.events.balance.flush", {});
55215
- setSatsBalanceResult(value);
55216
- }
55217
- };
55218
- const flushIncomingEvent = () => {
55219
- incomingEvent.timer = null;
55220
- const balance = incomingEvent.balance;
55221
- incomingEvent.balance = null;
55222
- if (balance != null) {
55223
- setBalance(balance);
55224
- }
55225
- markDiag(diag, "wallet.events.incoming.flush", { hasBalance: balance != null });
55226
- updateWalletData({ transfers: true, balance: false, reason: "incoming" });
55142
+ function createWalletEvents({ wallet, getTransferState, setTokenBalances, setSatsBalanceResult, reconcile, sync, diag }) {
55143
+ let closed = false;
55144
+ let balanceTimer = null;
55145
+ let claimTimer = null;
55146
+ let balanceValue = null;
55147
+ const claimedIds = new Set;
55148
+ const handleBalanceUpdate = (value) => {
55149
+ if (closed || !value || typeof value !== "object")
55150
+ return;
55151
+ balanceValue = value;
55152
+ if (balanceTimer)
55153
+ return;
55154
+ balanceTimer = setTimeout(() => {
55155
+ balanceTimer = null;
55156
+ if (!closed)
55157
+ setSatsBalanceResult(balanceValue);
55158
+ }, BALANCE_EVENT_COALESCE_MS);
55227
55159
  };
55228
- const flushClaimedEvent = () => {
55229
- claimedEvent.timer = null;
55230
- const balance = claimedEvent.balance;
55231
- const transfers = claimedEvent.transfers;
55232
- const ids = claimedEvent.ids;
55233
- claimedEvent.balance = null;
55234
- claimedEvent.transfers = [];
55235
- claimedEvent.ids = [];
55236
- if (balance != null) {
55237
- setBalance(balance);
55238
- }
55239
- markDiag(diag, "wallet.events.transfer.claimed.flush", { count: transfers.length, ids: ids.length, hasBalance: balance != null });
55240
- const transferState = getTransferState();
55241
- if (transfers.length) {
55242
- transferState.rememberTransfer?.(transfers, { completed: true, incoming: true });
55243
- }
55244
- if (ids.length) {
55245
- const completedIds = new Set(transferState.markTransfersCompleted?.(ids) || []);
55246
- const unknownIds = ids.filter((id) => !completedIds.has(String(id)));
55247
- if (unknownIds.length) {
55248
- transferState.refreshPendingTransfers?.(unknownIds);
55249
- }
55250
- }
55160
+ const handleTransferClaimed = (id) => {
55161
+ if (closed || !id)
55162
+ return;
55163
+ claimedIds.add(String(id));
55164
+ if (claimTimer)
55165
+ return;
55166
+ claimTimer = setTimeout(() => {
55167
+ claimTimer = null;
55168
+ const ids = [...claimedIds];
55169
+ claimedIds.clear();
55170
+ if (closed)
55171
+ return;
55172
+ const transfers = getTransferState();
55173
+ transfers.markTransfersCompleted(ids);
55174
+ transfers.refreshPendingTransfers(ids).finally(sync);
55175
+ sync();
55176
+ markDiag(diag, "wallet.events.transfer.claimed.flush", { count: ids.length });
55177
+ }, INCOMING_UPDATE_COALESCE_MS);
55251
55178
  };
55252
55179
  const handleTokenBalanceUpdate = (event) => {
55253
- if (event?.tokenBalances instanceof Map) {
55180
+ if (!closed && event?.tokenBalances instanceof Map)
55254
55181
  setTokenBalances(new Map(event.tokenBalances));
55255
- }
55256
55182
  };
55257
- const handleBalanceUpdate = (nextSatsBalance) => {
55258
- if (!nextSatsBalance || typeof nextSatsBalance !== "object") {
55259
- return;
55260
- }
55261
- balanceEvent.value = nextSatsBalance;
55262
- if (!balanceEvent.timer) {
55263
- balanceEvent.timer = setTimeout(flushBalanceEvent, BALANCE_EVENT_COALESCE_MS);
55264
- }
55183
+ const handleDepositConfirmed = () => {
55184
+ if (!closed)
55185
+ reconcile({ history: true, reason: "deposit-confirmed" });
55265
55186
  };
55266
- const handleIncomingBalance = (updatedBalance) => {
55267
- if (updatedBalance != null) {
55268
- incomingEvent.balance = updatedBalance;
55269
- }
55270
- if (!incomingEvent.timer) {
55271
- incomingEvent.timer = setTimeout(flushIncomingEvent, INCOMING_UPDATE_COALESCE_MS);
55272
- }
55187
+ const handleConnected = () => {
55188
+ if (!closed)
55189
+ reconcile({ history: true, pending: true, reason: "stream-connected" });
55273
55190
  };
55274
- const handleTransferClaimed = (transferId, updatedBalance, transfer) => {
55275
- if (updatedBalance != null) {
55276
- claimedEvent.balance = updatedBalance;
55277
- }
55278
- if (transfer) {
55279
- claimedEvent.transfers.push(transfer);
55280
- } else if (transferId) {
55281
- claimedEvent.ids.push(String(transferId));
55282
- }
55283
- if (!claimedEvent.timer) {
55284
- claimedEvent.timer = setTimeout(flushClaimedEvent, INCOMING_UPDATE_COALESCE_MS);
55285
- }
55191
+ const handleReconnecting = () => {
55192
+ markDiag(diag, "wallet.stream.reconnecting", {});
55286
55193
  };
55287
- const handleDepositConfirmed = (_id, updatedBalance) => {
55288
- handleIncomingBalance(updatedBalance);
55194
+ const handlers = {
55195
+ [WALLET_EVENTS.balance]: handleBalanceUpdate,
55196
+ [WALLET_EVENTS.tokenBalance]: handleTokenBalanceUpdate,
55197
+ [WALLET_EVENTS.transferClaimed]: handleTransferClaimed,
55198
+ [WALLET_EVENTS.depositConfirmed]: handleDepositConfirmed,
55199
+ "stream:connected": handleConnected,
55200
+ "stream:reconnecting": handleReconnecting
55289
55201
  };
55290
- wallet.on(WALLET_EVENTS.balance, handleBalanceUpdate);
55291
- wallet.on(WALLET_EVENTS.tokenBalance, handleTokenBalanceUpdate);
55292
- wallet.on(WALLET_EVENTS.depositConfirmed, handleDepositConfirmed);
55293
- wallet.on(WALLET_EVENTS.transferClaimed, handleTransferClaimed);
55202
+ for (const [name, handler] of Object.entries(handlers))
55203
+ wallet.on(name, handler);
55294
55204
  return {
55295
55205
  close() {
55296
- wallet.off(WALLET_EVENTS.balance, handleBalanceUpdate);
55297
- wallet.off(WALLET_EVENTS.tokenBalance, handleTokenBalanceUpdate);
55298
- wallet.off(WALLET_EVENTS.depositConfirmed, handleDepositConfirmed);
55299
- wallet.off(WALLET_EVENTS.transferClaimed, handleTransferClaimed);
55300
- for (const event of [balanceEvent, incomingEvent, claimedEvent]) {
55301
- if (event.timer) {
55302
- clearTimeout(event.timer);
55303
- event.timer = null;
55304
- }
55305
- }
55206
+ closed = true;
55207
+ clearTimeout(balanceTimer);
55208
+ clearTimeout(claimTimer);
55209
+ claimedIds.clear();
55210
+ for (const [name, handler] of Object.entries(handlers))
55211
+ wallet.off(name, handler);
55306
55212
  }
55307
55213
  };
55308
55214
  }
55309
- function createWalletPolling({ wallet, network, appState, getTransferState, getBalanceState, refreshClaims, activeTransferRefreshMs = ACTIVE_TRANSFER_REFRESH_RATE, diag }) {
55310
- let pollInterval = null;
55311
- let activeRefreshInterval = null;
55312
- let activeRefreshPromise = null;
55313
- let pendingPollPromise = null;
55314
- let activeRefreshLastAt = 0;
55315
- let transferDiscoveryVisible = false;
55215
+ function createWalletReconciliation({ network, appState, getTransferState, updateWalletData, claimDeposits, deferBackgroundWork = null, backgroundSignal = null, diag }) {
55216
+ const waits = createOwnedWaits();
55217
+ const depositRate = getDepositClaimPollMs(network);
55218
+ let started = false;
55219
+ let starting = false;
55316
55220
  let closed = false;
55317
- const depositClaimRate = getDepositClaimPollMs(network);
55318
- const activeRefreshPollMs = Math.max(500, Number(activeTransferRefreshMs) || ACTIVE_TRANSFER_REFRESH_RATE);
55319
- const isActive = () => !appState?.currentState || appState.currentState === "active";
55320
- const isTxReady = () => getTransferState().txReady === true && getBalanceState().balanceReady === true;
55321
- const hasActivePendingClaim = () => getTransferState().hasActivePendingClaim?.() === true;
55322
- const hasFastActiveRefreshWork = () => transferDiscoveryVisible || hasActivePendingClaim();
55323
- const activeRefreshDue = () => {
55324
- if (!hasFastActiveRefreshWork())
55325
- return false;
55326
- return hasActivePendingClaim() || !activeRefreshLastAt || Date.now() - activeRefreshLastAt >= activeRefreshPollMs;
55327
- };
55328
- const runActiveRefresh = (reason = "active-poll") => {
55329
- if (closed || !wallet || !isActive()) {
55330
- return Promise.resolve([]);
55331
- }
55332
- if (activeRefreshPromise) {
55333
- return activeRefreshPromise;
55334
- }
55335
- const promise = (async () => {
55336
- activeRefreshLastAt = Date.now();
55337
- const transferState = getTransferState();
55338
- const transfers = typeof transferState.claimPendingIncomingTransfers === "function" ? await transferState.claimPendingIncomingTransfers(reason) : [];
55339
- const claimActive = hasActivePendingClaim();
55340
- if (isTxReady() && typeof transferState.refreshPendingTransfers === "function" && !transferDiscoveryVisible && !claimActive) {
55341
- transferState.refreshPendingTransfers(null, { cold: true, reason });
55342
- }
55343
- return transfers;
55344
- })().finally(() => {
55345
- if (activeRefreshPromise === promise) {
55346
- activeRefreshPromise = null;
55347
- }
55348
- });
55349
- activeRefreshPromise = promise;
55350
- return promise;
55351
- };
55352
- const stopActiveRefreshPoll = () => {
55353
- if (!activeRefreshInterval)
55354
- return;
55355
- clearInterval(activeRefreshInterval);
55356
- activeRefreshInterval = null;
55221
+ let timer = null;
55222
+ let promise = null;
55223
+ let queued = null;
55224
+ const waiters = [];
55225
+ const finishWaiters = () => {
55226
+ for (const resolve of waiters.splice(0))
55227
+ resolve();
55357
55228
  };
55358
- const runObservedActiveRefresh = () => {
55359
- if (!hasFastActiveRefreshWork()) {
55360
- stopActiveRefreshPoll();
55361
- return;
55362
- }
55363
- if (activeRefreshDue()) {
55364
- runActiveRefresh();
55365
- }
55229
+ let pendingAt = 0;
55230
+ let repairAt = 0;
55231
+ let depositAt = 0;
55232
+ const isActive = () => !appState?.currentState || appState.currentState === "active";
55233
+ const isOpen = () => !closed && !backgroundSignal?.aborted;
55234
+ const hasPending = () => {
55235
+ const state = getTransferState();
55236
+ return state.hasPendingTxs || state.hasRequestedTransfers();
55366
55237
  };
55367
- const startActiveRefreshPoll = () => {
55368
- if (closed || !appState || activeRefreshInterval || !wallet || !isActive() || !hasFastActiveRefreshWork() || typeof getTransferState().claimPendingIncomingTransfers !== "function") {
55238
+ function sync() {
55239
+ clearTimeout(timer);
55240
+ timer = null;
55241
+ if (!isOpen() || !started || !isActive() || promise)
55369
55242
  return;
55370
- }
55371
- markDiag(diag, "wallet.pendingTxs.active.start", {});
55372
- activeRefreshInterval = setInterval(() => {
55373
- if (!isActive()) {
55374
- return;
55375
- }
55376
- runObservedActiveRefresh();
55377
- }, activeRefreshPollMs);
55378
- runObservedActiveRefresh();
55379
- };
55380
- const runPendingPoll = () => {
55381
- if (pendingPollPromise) {
55382
- return pendingPollPromise;
55383
- }
55384
- const promise = Promise.resolve().then(() => getTransferState().refreshPendingTransfers?.()).finally(() => {
55385
- if (pendingPollPromise === promise) {
55386
- pendingPollPromise = null;
55243
+ const next = Math.min(repairAt, depositAt, hasPending() ? pendingAt : Infinity);
55244
+ timer = setTimeout(tick, Math.max(0, next - Date.now()));
55245
+ }
55246
+ function request(options = {}) {
55247
+ if (!isOpen())
55248
+ return Promise.resolve();
55249
+ queued = {
55250
+ history: queued?.history || options.history === true,
55251
+ incoming: queued?.incoming || options.incoming === true,
55252
+ pending: queued?.pending || options.pending === true,
55253
+ deposits: queued?.deposits || options.deposits === true,
55254
+ forcePending: queued?.forcePending || options.pending === true && options.reason !== "scheduled",
55255
+ reason: queued?.reason && queued.reason !== options.reason ? "merged" : options.reason || "manual"
55256
+ };
55257
+ const result = new Promise((resolve) => waiters.push(resolve));
55258
+ if (!started || !isActive() || promise)
55259
+ return result;
55260
+ clearTimeout(timer);
55261
+ const run = async () => {
55262
+ while (queued && isOpen() && isActive()) {
55263
+ const work = queued;
55264
+ queued = null;
55265
+ const startedAt = Date.now();
55266
+ try {
55267
+ if (work.incoming) {
55268
+ repairAt = Date.now() + WALLET_TRANSFER_REPAIR_MS;
55269
+ await getTransferState().claimPendingIncomingTransfers(work.reason);
55270
+ }
55271
+ if (!isOpen())
55272
+ break;
55273
+ if (!isActive()) {
55274
+ request(work);
55275
+ break;
55276
+ }
55277
+ if (work.deposits) {
55278
+ depositAt = Date.now() + depositRate;
55279
+ if (await claimDeposits())
55280
+ work.history = true;
55281
+ }
55282
+ if (!isOpen())
55283
+ break;
55284
+ if (!isActive()) {
55285
+ request(work);
55286
+ break;
55287
+ }
55288
+ if (work.history)
55289
+ await updateWalletData({ force: true, reason: work.reason });
55290
+ if (!isOpen())
55291
+ break;
55292
+ if (!isActive()) {
55293
+ request(work);
55294
+ break;
55295
+ }
55296
+ if (work.pending) {
55297
+ pendingAt = Date.now() + POLL_TXS_RATE;
55298
+ await getTransferState().refreshPendingTransfers(null, { force: work.forcePending, reason: work.reason });
55299
+ }
55300
+ if (!isOpen())
55301
+ break;
55302
+ if (!isActive()) {
55303
+ request(work);
55304
+ break;
55305
+ }
55306
+ markDone(diag, "wallet.reconcile", startedAt, work);
55307
+ } catch (error) {
55308
+ markError(diag, "wallet.reconcile", startedAt, error, { reason: work.reason });
55309
+ }
55387
55310
  }
55311
+ };
55312
+ const running = Promise.resolve().then(run).finally(() => {
55313
+ if (promise === running)
55314
+ promise = null;
55315
+ if (!queued)
55316
+ finishWaiters();
55317
+ sync();
55388
55318
  });
55389
- pendingPollPromise = promise;
55390
- return promise;
55391
- };
55392
- const startPoll = () => {
55393
- const transferState = getTransferState();
55394
- if (closed || pollInterval || !wallet || !transferState.hasPendingTxs || !isTxReady() || !isActive()) {
55395
- return;
55396
- }
55397
- runPendingPoll();
55398
- pollInterval = setInterval(() => {
55399
- if (isActive()) {
55400
- runPendingPoll();
55401
- }
55402
- }, POLL_TXS_RATE);
55403
- };
55404
- const stopPoll = () => {
55405
- if (!pollInterval)
55406
- return;
55407
- clearInterval(pollInterval);
55408
- pollInterval = null;
55409
- };
55410
- const sync = () => {
55411
- if (closed || !wallet) {
55412
- stopPoll();
55413
- stopActiveRefreshPoll();
55414
- return;
55415
- }
55416
- if (isActive() && hasFastActiveRefreshWork()) {
55417
- startActiveRefreshPoll();
55418
- } else {
55419
- stopActiveRefreshPoll();
55420
- }
55421
- if (getTransferState().hasPendingTxs && isActive()) {
55422
- startPoll();
55423
- } else {
55424
- stopPoll();
55319
+ promise = running;
55320
+ return result;
55321
+ }
55322
+ function tick() {
55323
+ timer = null;
55324
+ const now = Date.now();
55325
+ const incoming = now >= repairAt;
55326
+ const deposits = now >= depositAt;
55327
+ const pending = hasPending() && now >= pendingAt;
55328
+ if (incoming)
55329
+ repairAt = now + WALLET_TRANSFER_REPAIR_MS;
55330
+ if (deposits)
55331
+ depositAt = now + depositRate;
55332
+ if (pending)
55333
+ pendingAt = now + POLL_TXS_RATE;
55334
+ request({ incoming, deposits, pending, reason: "scheduled" });
55335
+ }
55336
+ const subscription = appState?.addEventListener?.("change", (state) => {
55337
+ if (state === "active") {
55338
+ request({ incoming: true, history: true, pending: true, deposits: true, reason: "resume" });
55425
55339
  }
55426
- };
55427
- const setTransferDiscoveryVisible = (visible) => {
55428
- const next = visible === true;
55429
- if (transferDiscoveryVisible === next)
55430
- return;
55431
- transferDiscoveryVisible = next;
55432
- if (next)
55433
- activeRefreshLastAt = 0;
55434
55340
  sync();
55435
- };
55436
- const appStateSubscription = appState?.addEventListener?.("change", (nextState2) => {
55437
- if (nextState2 === "active") {
55438
- runActiveRefresh("focus");
55439
- startActiveRefreshPoll();
55440
- if (getTransferState().hasPendingTxs) {
55441
- startPoll();
55442
- runPendingPoll();
55443
- }
55444
- refreshClaims();
55445
- return;
55446
- }
55447
- stopPoll();
55448
- stopActiveRefreshPoll();
55449
55341
  });
55450
- const depositClaimInterval = setInterval(() => {
55451
- if (isActive()) {
55452
- refreshClaims();
55453
- }
55454
- }, depositClaimRate);
55455
- sync();
55456
55342
  return {
55457
- setTransferDiscoveryVisible,
55458
- stopPoll,
55343
+ request,
55344
+ refresh: () => request({ incoming: true, history: true, pending: true, deposits: true, reason: "manual" }),
55459
55345
  sync,
55460
- close() {
55461
- if (closed)
55346
+ async start() {
55347
+ if (starting || !isOpen())
55462
55348
  return;
55463
- closed = true;
55464
- stopPoll();
55465
- stopActiveRefreshPoll();
55466
- clearInterval(depositClaimInterval);
55467
- appStateSubscription?.remove?.();
55468
- }
55469
- };
55470
- }
55471
- function createWalletBoot({ wallet, getTransferState, getBalance, getRecentTxs, deferBackgroundWork = null, backgroundSignal = null, stopPoll, diag }) {
55472
- let closed = false;
55473
- const waits = createOwnedWaits();
55474
- const boot = async () => {
55475
- const startedAt = Date.now();
55476
- markDiag(diag, "wallet.provider.boot.start", {});
55477
- await waits.delay(BOOT_CACHE_DECISION_DELAY_MS);
55478
- await waits.idle({ timeout: BOOT_REFRESH_DELAY_MS, delay: BOOT_REFRESH_DELAY_MS });
55479
- if (closed) {
55480
- markDone(diag, "wallet.provider.boot", startedAt, { cancelled: true });
55481
- return;
55482
- }
55483
- const transferState = getTransferState();
55484
- if (transferState.txReady) {
55485
- const cachedTransferCount = transferState.transferCount;
55486
- markDone(diag, "wallet.provider.boot", startedAt, {
55487
- cancelled: false,
55488
- cachedTxReady: true,
55489
- deferredTxRefresh: true,
55490
- deferredBalanceRefresh: true,
55491
- firstTxCount: cachedTransferCount
55492
- });
55493
- await waits.delay(BOOT_CACHED_REFRESH_DELAY_MS);
55494
- if (closed)
55349
+ starting = true;
55350
+ await waits.delay(BOOT_CACHE_DECISION_DELAY_MS);
55351
+ await waits.idle({ timeout: BOOT_REFRESH_DELAY_MS, delay: BOOT_REFRESH_DELAY_MS });
55352
+ if (!isOpen())
55495
55353
  return;
55496
- if (typeof deferBackgroundWork === "function") {
55354
+ if (getTransferState().txReady)
55355
+ await waits.delay(BOOT_CACHED_REFRESH_DELAY_MS);
55356
+ if (!isOpen())
55357
+ return;
55358
+ if (deferBackgroundWork)
55497
55359
  await deferBackgroundWork("wallet.boot.refresh", { signal: backgroundSignal });
55498
- } else {
55499
- await waits.idle({ timeout: BOOT_REFRESH_DELAY_MS, delay: BOOT_REFRESH_DELAY_MS });
55500
- }
55501
- if (closed)
55360
+ if (!isOpen())
55502
55361
  return;
55503
- const refreshStartedAt = Date.now();
55504
- markDiag(diag, "wallet.provider.boot.refresh.start", { balance: true, transfers: true });
55505
- try {
55506
- const [, recent] = await Promise.all([getBalance(), getRecentTxs({ force: true, includePending: false, reason: "boot-cache" })]);
55507
- markDone(diag, "wallet.provider.boot.refresh", refreshStartedAt, {
55508
- balance: true,
55509
- transfers: true,
55510
- count: recent?.transfers?.length || 0
55511
- });
55512
- } catch (error) {
55513
- markError(diag, "wallet.provider.boot.refresh", refreshStartedAt, error);
55514
- }
55515
- return;
55516
- }
55517
- if (typeof deferBackgroundWork === "function") {
55518
- await deferBackgroundWork("wallet.boot.initial", { signal: backgroundSignal });
55519
- }
55520
- if (closed) {
55521
- markDone(diag, "wallet.provider.boot", startedAt, { cancelled: true });
55522
- return;
55523
- }
55524
- const [, firstTxPage] = await Promise.all([getBalance(), getRecentTxs({ reason: "boot", includePending: false })]);
55525
- markDone(diag, "wallet.provider.boot", startedAt, {
55526
- cancelled: closed,
55527
- cachedTxReady: false,
55528
- deferredTxRefresh: false,
55529
- firstTxCount: firstTxPage?.transfers?.length || 0,
55530
- firstTxHasMore: !!firstTxPage?.hasMore,
55531
- cachedHistoryComplete: firstTxPage?.cachedHistoryComplete === true,
55532
- reconcileCount: Array.isArray(firstTxPage?.reconcileIds) ? firstTxPage.reconcileIds.length : 0
55533
- });
55534
- };
55535
- if (wallet) {
55536
- boot();
55537
- }
55538
- return {
55362
+ started = true;
55363
+ const now = Date.now();
55364
+ pendingAt = now + POLL_TXS_RATE;
55365
+ repairAt = now + WALLET_TRANSFER_REPAIR_MS;
55366
+ depositAt = now + depositRate;
55367
+ await request({ history: true, pending: true, reason: "boot" });
55368
+ },
55539
55369
  close() {
55540
- if (closed)
55541
- return;
55542
55370
  closed = true;
55371
+ queued = null;
55372
+ finishWaiters();
55543
55373
  waits.close();
55544
- markDiag(diag, "wallet.provider.boot.stop", {});
55545
- stopPoll();
55374
+ clearTimeout(timer);
55375
+ subscription?.remove?.();
55546
55376
  }
55547
55377
  };
55548
55378
  }
@@ -56009,18 +55839,6 @@ function createWalletPrivacy({ wallet, ghostWallet, diag }) {
56009
55839
  };
56010
55840
  }
56011
55841
 
56012
- // ../../core/wallet/history.js
56013
- function transferPage(page, currentOffset, limit) {
56014
- const transfers = Array.isArray(page?.transfers) ? page.transfers : [];
56015
- const returnedOffset = Number(page?.offset);
56016
- const nextOffset = Number.isFinite(returnedOffset) && returnedOffset > currentOffset ? returnedOffset : currentOffset + transfers.length;
56017
- return {
56018
- transfers,
56019
- nextOffset,
56020
- hasMore: transfers.length >= limit
56021
- };
56022
- }
56023
-
56024
55842
  // ../../core/wallet/transferdata.js
56025
55843
  var RECENT_TRANSFER_LIMIT = WALLET_RECENT_TRANSFER_LIMIT;
56026
55844
  var TRANSFER_PAGE_LIMIT = WALLET_TRANSFER_PAGE_LIMIT;
@@ -56191,16 +56009,6 @@ function getOldestTransferMs(transfers = []) {
56191
56009
  }
56192
56010
  return oldest;
56193
56011
  }
56194
- function getOldestAnyTransferMs(transfers = []) {
56195
- let oldest = null;
56196
- for (const tx of transfers) {
56197
- const ms = txCreatedMs(tx);
56198
- if (!ms)
56199
- continue;
56200
- oldest = oldest == null ? ms : Math.min(oldest, ms);
56201
- }
56202
- return oldest;
56203
- }
56204
56012
  function shouldReplaceTransfer(current, next) {
56205
56013
  return isPendingTransfer(current) && (!isPendingTransfer(next) || current?.status !== next?.status || txUpdatedMs(next) > txUpdatedMs(current));
56206
56014
  }
@@ -56463,14 +56271,6 @@ function reconciliationDue(owner, transfer, id, now) {
56463
56271
  const retryMs = getPendingTransferRetryMs(transfer, ageMs, owner.unresolvedCount.get(id) || 0);
56464
56272
  return retryMs <= 0 || now - lastAttemptAt >= retryMs;
56465
56273
  }
56466
- async function stillPendingTransferIds(wallet, ids = []) {
56467
- const selectedIds = transferIds2(ids);
56468
- if (!selectedIds.length || typeof wallet?.transferService?.queryPendingTransfers !== "function")
56469
- return new Set;
56470
- const requestedIds = new Set(selectedIds);
56471
- const page = await wallet.transferService.queryPendingTransfers.call(wallet.transferService, selectedIds);
56472
- return new Set((Array.isArray(page?.transfers) ? page.transfers : []).map((transfer) => String(transfer?.id || "")).filter((id) => id && requestedIds.has(id)));
56473
- }
56474
56274
  function normalizeCursor(owner, transfers = owner.snapshot.getTransfers()) {
56475
56275
  const count = pendingTransferIds(transfers).length;
56476
56276
  if (!count) {
@@ -56571,8 +56371,10 @@ async function refreshRequestedTransfers(owner, ids = []) {
56571
56371
  const requestedIds = transferIds2(ids);
56572
56372
  if (!requestedIds.length)
56573
56373
  return [];
56574
- for (const id of requestedIds)
56374
+ for (const id of requestedIds) {
56575
56375
  owner.requestedIds.add(id);
56376
+ owner.hydrationDue.set(id, Date.now() + WALLET_TRANSFER_POLL_MS);
56377
+ }
56576
56378
  if (owner.requestedPromise) {
56577
56379
  markDiag(owner.diag, "wallet.pendingTxs.requested.queue", { count: requestedIds.length });
56578
56380
  return owner.requestedPromise;
@@ -56580,56 +56382,44 @@ async function refreshRequestedTransfers(owner, ids = []) {
56580
56382
  const run = async () => {
56581
56383
  let latestTransfers = [];
56582
56384
  while (isCurrentGeneration(owner, generation) && owner.requestedIds.size) {
56583
- const batchIds = [...owner.requestedIds];
56584
- owner.requestedIds.clear();
56385
+ const batchIds = [...owner.requestedIds].slice(0, COLD_BATCH_SIZE);
56386
+ for (const id of batchIds)
56387
+ owner.requestedIds.delete(id);
56585
56388
  const batchIdSet = new Set(batchIds);
56586
56389
  const startedAt = Date.now();
56587
56390
  markDiag(owner.diag, "wallet.pendingTxs.requested.start", { requested: batchIds.length });
56588
56391
  try {
56589
56392
  const baseTransfers = owner.snapshot.getTransfers();
56590
56393
  const baseById = new Map(baseTransfers.map((transfer) => [String(transfer?.id || ""), transfer]));
56591
- let pages = 0;
56592
- let pageTransfers = [];
56593
- let fetchedTransfers = await owner.reads.byIds(batchIds);
56394
+ const fetchedTransfers = await owner.reads.byIds(batchIds);
56594
56395
  if (!isCurrentGeneration(owner, generation))
56595
56396
  return [];
56596
- if (!fetchedTransfers) {
56597
- if (batchIds.length === 1) {
56598
- const transfer = await owner.reads.byId(batchIds[0]);
56599
- fetchedTransfers = transfer ? [transfer] : [];
56600
- } else {
56601
- const result = await owner.reads.recentPages(batchIds, baseTransfers);
56602
- pages = result.pages;
56603
- pageTransfers = result.transfers;
56604
- fetchedTransfers = pageTransfers;
56605
- }
56606
- }
56607
- if (!isCurrentGeneration(owner, generation))
56608
- return [];
56609
- const updates = fetchedTransfers.map((transfer) => {
56397
+ const updates = fetchedTransfers.filter((transfer) => batchIdSet.has(String(transfer?.id)) && transferBelongsToWallet(compactTransfer(transfer), owner.walletPK)).map((transfer) => {
56610
56398
  const id = String(transfer?.id || "");
56611
56399
  const current = id ? baseById.get(id) : null;
56612
56400
  return current?.transferDirection && !transfer?.transferDirection ? { ...transfer, transferDirection: current.transferDirection } : transfer;
56613
56401
  });
56614
56402
  forgetResolvedFetched(owner, updates);
56615
- const nextTransfers = updates.length ? mergeTransferPageForWallet(baseTransfers, updates, owner.walletPK, "append") : baseTransfers;
56403
+ const currentTransfers = owner.snapshot.getTransfers();
56404
+ const nextTransfers = updates.length ? overlayPending(owner, mergeTransferPageForWallet(currentTransfers, updates, owner.walletPK, "append")) : currentTransfers;
56616
56405
  const requestedTransfers = nextTransfers.filter((transfer) => batchIdSet.has(String(transfer?.id || "")));
56617
56406
  const claimCandidates = owner.claims.candidates(pendingIncomingTransfers(requestedTransfers));
56618
56407
  const resolvedIds = requestedTransfers.filter((transfer) => !isPendingTransfer(transfer)).map((transfer) => String(transfer.id));
56619
56408
  forgetPending(owner, resolvedIds);
56620
- if (nextTransfers !== baseTransfers) {
56409
+ if (nextTransfers !== currentTransfers) {
56621
56410
  await owner.snapshot.commitConfirmed(requestedTransfers.filter((transfer) => !isPendingTransfer(transfer)), { position: "prepend" });
56622
56411
  if (!isCurrentGeneration(owner, generation))
56623
56412
  return [];
56624
- owner.snapshot.replace(nextTransfers);
56413
+ owner.snapshot.replace(mergeTransferPageForWallet(owner.snapshot.getTransfers(), updates, owner.walletPK, "append"));
56625
56414
  owner.snapshot.setReady();
56626
56415
  }
56416
+ for (const transfer of updates)
56417
+ owner.hydrationDue.delete(String(transfer.id));
56627
56418
  if (claimCandidates.length)
56628
56419
  owner.claims.enqueue(claimCandidates, "requested");
56629
56420
  markDone(owner.diag, "wallet.pendingTxs.requested", startedAt, {
56630
56421
  requested: batchIds.length,
56631
- pages,
56632
- pageCount: pageTransfers.length,
56422
+ pages: 0,
56633
56423
  updateCount: updates.length,
56634
56424
  found: requestedTransfers.length,
56635
56425
  resolved: resolvedIds.length,
@@ -56654,7 +56444,7 @@ async function refreshRequestedTransfers(owner, ids = []) {
56654
56444
  owner.requestedPromise = request;
56655
56445
  return request;
56656
56446
  }
56657
- function planPendingReconciliation(owner, { startedAt, cold, reason }) {
56447
+ function planPendingReconciliation(owner, { startedAt, cold, reason, force }) {
56658
56448
  const previousTransfers = owner.snapshot.getTransfers();
56659
56449
  const pendingList = pendingTransfers(previousTransfers);
56660
56450
  const pendingById = syncReconciliationAges(owner, pendingList, startedAt);
@@ -56666,11 +56456,13 @@ function planPendingReconciliation(owner, { startedAt, cold, reason }) {
56666
56456
  const transfer = pendingById.get(id);
56667
56457
  if (cold && transfer && isIncomingTransfer(transfer))
56668
56458
  return false;
56459
+ if (force)
56460
+ return true;
56669
56461
  if (bootGraceActive && transfer && !owner.rememberedIds.has(id) && !isIncomingTransfer(transfer))
56670
56462
  return false;
56671
56463
  return reconciliationDue(owner, transfer, id, startedAt);
56672
56464
  });
56673
- const limit = Math.min(cold ? COLD_BATCH_SIZE : STATUS_BATCH_SIZE, candidateIds.length);
56465
+ const limit = Math.min(cold || force ? COLD_BATCH_SIZE : STATUS_BATCH_SIZE, candidateIds.length);
56674
56466
  const selectedIds = rotateIds(candidateIds, owner.cursor, limit);
56675
56467
  if (candidateIds.length)
56676
56468
  owner.cursor = (owner.cursor + selectedIds.length) % candidateIds.length;
@@ -56699,58 +56491,45 @@ async function readPendingReconciliation(owner, plan, generation) {
56699
56491
  const baseTransfers = currentTransfers.length ? currentTransfers : plan.previousTransfers;
56700
56492
  const baseById = new Map(baseTransfers.map((transfer) => [String(transfer?.id || ""), transfer]));
56701
56493
  const resolvedIds = [];
56702
- const completedOverlayIds = [];
56703
56494
  const updates = [];
56704
- let actualChecked = 0;
56705
56495
  let unresolvedOutgoing = 0;
56706
56496
  let maxUnresolvedCount = 0;
56707
- if (plan.incomingIds.length) {
56708
- const stillPending = await stillPendingTransferIds(owner.wallet, plan.incomingIds);
56709
- if (!isCurrentGeneration(owner, generation))
56710
- return null;
56711
- const resolvedIncoming = plan.incomingIds.filter((id) => !stillPending.has(id));
56712
- resolvedIds.push(...resolvedIncoming);
56713
- completedOverlayIds.push(...resolvedIncoming);
56714
- }
56715
- if (plan.outgoingIds.length) {
56716
- const fetched = await owner.reads.byIds(plan.outgoingIds, { fallbackToSingles: true }) || [];
56717
- if (!isCurrentGeneration(owner, generation))
56718
- return null;
56719
- actualChecked = fetched.length;
56720
- const fetchedById = new Map(fetched.map((transfer) => [String(transfer?.id || ""), transfer]));
56721
- for (const id of plan.outgoingIds) {
56722
- const transfer = fetchedById.get(id);
56723
- if (!transfer)
56724
- continue;
56725
- const current = baseById.get(id);
56726
- const update = current?.transferDirection && !transfer?.transferDirection ? { ...transfer, transferDirection: current.transferDirection } : transfer;
56727
- updates.push(update);
56728
- if (!isPendingTransfer(update)) {
56729
- resolvedIds.push(id);
56730
- owner.unresolvedCount.delete(id);
56731
- } else {
56732
- const count = (owner.unresolvedCount.get(id) || 0) + 1;
56733
- owner.unresolvedCount.set(id, count);
56734
- unresolvedOutgoing += 1;
56735
- maxUnresolvedCount = Math.max(maxUnresolvedCount, count);
56736
- }
56497
+ const fetched = await owner.reads.byIds(plan.selectedIds);
56498
+ if (!isCurrentGeneration(owner, generation))
56499
+ return null;
56500
+ const actualChecked = fetched.length;
56501
+ const selected = new Set(plan.selectedIds);
56502
+ for (const transfer of fetched) {
56503
+ const id = String(transfer?.id || "");
56504
+ if (!selected.has(id) || !transferBelongsToWallet(compactTransfer(transfer), owner.walletPK))
56505
+ continue;
56506
+ const current = baseById.get(id);
56507
+ const update = current?.transferDirection && !transfer?.transferDirection ? { ...transfer, transferDirection: current.transferDirection } : transfer;
56508
+ updates.push(update);
56509
+ if (!isPendingTransfer(update)) {
56510
+ resolvedIds.push(id);
56511
+ owner.unresolvedCount.delete(id);
56512
+ } else if (!isIncomingTransfer(update)) {
56513
+ const count = (owner.unresolvedCount.get(id) || 0) + 1;
56514
+ owner.unresolvedCount.set(id, count);
56515
+ unresolvedOutgoing += 1;
56516
+ maxUnresolvedCount = Math.max(maxUnresolvedCount, count);
56737
56517
  }
56738
56518
  }
56739
- return { baseTransfers, resolvedIds, completedOverlayIds, updates, actualChecked, unresolvedOutgoing, maxUnresolvedCount };
56519
+ return { resolvedIds, updates, actualChecked, unresolvedOutgoing, maxUnresolvedCount };
56740
56520
  }
56741
56521
  async function commitPendingReconciliation(owner, plan, result, generation) {
56742
56522
  if (!result || !isCurrentGeneration(owner, generation))
56743
56523
  return null;
56744
- let nextTransfers = result.updates.length ? mergeTransferPageForWallet(result.baseTransfers, result.updates, owner.walletPK, "append") : result.baseTransfers;
56524
+ const current = owner.snapshot.getTransfers();
56525
+ const nextTransfers = result.updates.length ? overlayPending(owner, mergeTransferPageForWallet(current, result.updates, owner.walletPK, "append")) : current;
56745
56526
  forgetPending(owner, result.resolvedIds);
56746
- if (result.completedOverlayIds.length)
56747
- nextTransfers = markClaimedTransfersCompleted(nextTransfers, result.completedOverlayIds);
56748
- if (nextTransfers !== result.baseTransfers) {
56527
+ if (nextTransfers !== current) {
56749
56528
  const selectedIds = new Set(plan.selectedIds);
56750
56529
  await owner.snapshot.commitConfirmed(nextTransfers.filter((transfer) => selectedIds.has(String(transfer?.id)) && !isPendingTransfer(transfer)), { position: "prepend" });
56751
56530
  if (!isCurrentGeneration(owner, generation))
56752
56531
  return null;
56753
- owner.snapshot.replace(nextTransfers);
56532
+ owner.snapshot.replace(mergeTransferPageForWallet(owner.snapshot.getTransfers(), result.updates, owner.walletPK, "append"));
56754
56533
  owner.snapshot.setReady();
56755
56534
  }
56756
56535
  markDone(owner.diag, "wallet.pendingTxs.reconcile", plan.startedAt, {
@@ -56787,7 +56566,7 @@ async function reconcilePendingTransfers(owner, options = {}, generation = owner
56787
56566
  }
56788
56567
  if (cold)
56789
56568
  owner.coldRefreshAt = startedAt;
56790
- const plan = planPendingReconciliation(owner, { startedAt, cold, reason });
56569
+ const plan = planPendingReconciliation(owner, { startedAt, cold, reason, force: options.force === true });
56791
56570
  if (!plan.selectedIds.length)
56792
56571
  return [];
56793
56572
  if (!await owner.waitForWork("pending-reconcile", plan.eagerOutgoing ? { waitForSdkQuiet: false, idleMs: 0 } : undefined) || !isCurrentGeneration(owner, generation))
@@ -56821,29 +56600,38 @@ function refreshPending(owner, ids = null, options = {}) {
56821
56600
  const requestedIds = transferIds2(ids);
56822
56601
  if (requestedIds.length)
56823
56602
  return refreshRequestedTransfers(owner, requestedIds);
56824
- if (owner.claims.isActive())
56825
- return Promise.resolve([]);
56826
- const queuedClaims = owner.claims.queuedCount();
56827
- if (owner.isPendingQuery() || queuedClaims) {
56828
- markDiag(owner.diag, "wallet.pendingTxs.reconcile.defer", {
56829
- reason: owner.isPendingQuery() ? "pending-query" : "claim-queue",
56830
- queued: queuedClaims
56831
- });
56832
- return Promise.resolve([]);
56833
- }
56834
56603
  if (owner.promise) {
56835
56604
  owner.queuedAll = true;
56605
+ owner.queuedForce ||= options.force === true;
56836
56606
  return owner.promise;
56837
56607
  }
56838
- const request = reconcilePendingTransfers(owner, options, generation).finally(() => {
56608
+ const run = async () => {
56609
+ const dueIds = [...owner.hydrationDue].filter(([, due]) => options.force === true || due <= Date.now()).map(([id]) => id);
56610
+ if (dueIds.length)
56611
+ await refreshRequestedTransfers(owner, dueIds);
56612
+ if (!isCurrentGeneration(owner, generation) || owner.claims.isActive())
56613
+ return [];
56614
+ const queuedClaims = owner.claims.queuedCount();
56615
+ if (owner.isPendingQuery() || queuedClaims) {
56616
+ markDiag(owner.diag, "wallet.pendingTxs.reconcile.defer", {
56617
+ reason: owner.isPendingQuery() ? "pending-query" : "claim-queue",
56618
+ queued: queuedClaims
56619
+ });
56620
+ return [];
56621
+ }
56622
+ return reconcilePendingTransfers(owner, options, generation);
56623
+ };
56624
+ const request = run().finally(() => {
56839
56625
  if (owner.promise === request)
56840
56626
  owner.promise = null;
56841
56627
  if (!isCurrentGeneration(owner, generation))
56842
56628
  return;
56843
56629
  const queuedAll = owner.queuedAll;
56630
+ const force = owner.queuedForce;
56844
56631
  owner.queuedAll = false;
56632
+ owner.queuedForce = false;
56845
56633
  if (queuedAll)
56846
- refreshPending(owner);
56634
+ refreshPending(owner, null, { force });
56847
56635
  });
56848
56636
  owner.promise = request;
56849
56637
  return request;
@@ -56868,9 +56656,11 @@ function createPendingTransferReconciliation({ wallet, walletPK, outgoingSettleM
56868
56656
  attemptAt: new Map,
56869
56657
  unresolvedCount: new Map,
56870
56658
  requestedIds: new Set,
56659
+ hydrationDue: new Map,
56871
56660
  requestedPromise: null,
56872
56661
  promise: null,
56873
56662
  queuedAll: false,
56663
+ queuedForce: false,
56874
56664
  cursor: 0,
56875
56665
  coldRefreshAt: 0,
56876
56666
  graceUntil: 0,
@@ -56883,9 +56673,11 @@ function createPendingTransferReconciliation({ wallet, walletPK, outgoingSettleM
56883
56673
  owner.attemptAt.clear();
56884
56674
  owner.unresolvedCount.clear();
56885
56675
  owner.requestedIds.clear();
56676
+ owner.hydrationDue.clear();
56886
56677
  owner.requestedPromise = null;
56887
56678
  owner.promise = null;
56888
56679
  owner.queuedAll = false;
56680
+ owner.queuedForce = false;
56889
56681
  owner.cursor = 0;
56890
56682
  owner.coldRefreshAt = 0;
56891
56683
  owner.graceUntil = 0;
@@ -56901,11 +56693,24 @@ function createPendingTransferReconciliation({ wallet, walletPK, outgoingSettleM
56901
56693
  startBootGrace() {
56902
56694
  owner.graceUntil = Date.now() + WALLET_PENDING_TRANSFER_BOOT_GRACE_MS;
56903
56695
  },
56696
+ hasRequestedTransfers: () => owner.hydrationDue.size > 0,
56904
56697
  refresh: (ids, options) => refreshPending(owner, ids, options),
56905
56698
  reset
56906
56699
  });
56907
56700
  }
56908
56701
 
56702
+ // ../../core/wallet/history.js
56703
+ function transferPage(page, currentOffset, limit) {
56704
+ const transfers = Array.isArray(page?.transfers) ? page.transfers : [];
56705
+ const returnedOffset = Number(page?.offset);
56706
+ const nextOffset = Number.isFinite(returnedOffset) && returnedOffset > currentOffset ? returnedOffset : currentOffset + transfers.length;
56707
+ return {
56708
+ transfers,
56709
+ nextOffset,
56710
+ hasMore: transfers.length >= limit
56711
+ };
56712
+ }
56713
+
56909
56714
  // ../../core/wallet/transferhistorysync.js
56910
56715
  function isCurrentGeneration2(owner, generation) {
56911
56716
  return owner.generation === generation && !owner.isClosed();
@@ -58272,9 +58077,7 @@ function createWalletHistoryStore() {
58272
58077
  // ../../core/wallet/transfers.js
58273
58078
  var TRANSFER_FETCH_THROTTLE_MS = WALLET_TRANSFER_FETCH_THROTTLE_MS;
58274
58079
  var PENDING_TRANSFER_QUERY_PAGE_SIZE = TRANSFER_PAGE_LIMIT;
58275
- var PENDING_TRANSFER_RECONCILE_PAGE_SIZE = TRANSFER_PAGE_LIMIT;
58276
58080
  var SDK_BACKGROUND_QUIET_MS = Math.max(0, WALLET_SDK_BACKGROUND_QUIET_MS);
58277
- var PENDING_TRANSFER_RECONCILE_MAX_PAGES = 5;
58278
58081
  var PENDING_TRANSFER_CLAIM_RETRY_MS = WALLET_PENDING_TRANSFER_CLAIM_RETRY_MS;
58279
58082
  var PENDING_TRANSFER_OUTGOING_SETTLE_MS = PENDING_TRANSFER_CLAIM_RETRY_MS;
58280
58083
  async function getPendingIncomingTransfers(wallet, diag) {
@@ -58487,72 +58290,16 @@ function createWalletTransferSession({ wallet, walletPK, claimIncomingTransfers,
58487
58290
  }
58488
58291
  return queueWalletFetch(() => wallet.getTransfer(String(transferId2)));
58489
58292
  };
58490
- const fetchTransfersByIds = async (ids, { fallbackToSingles = false } = {}) => {
58293
+ const fetchTransfersByIds = async (ids) => {
58491
58294
  const transferIds3 = uniqueIds(ids);
58492
- if (!transferIds3.length) {
58295
+ if (!transferIds3.length)
58493
58296
  return [];
58494
- }
58495
- if (typeof wallet?.transferService?.getTransfersByIds !== "function") {
58496
- if (!fallbackToSingles) {
58497
- return null;
58498
- }
58499
- const transfers = [];
58500
- for (const transferId2 of transferIds3) {
58501
- const tx = await fetchTransferById(transferId2);
58502
- if (tx) {
58503
- transfers.push(tx);
58504
- }
58505
- }
58506
- return transfers;
58507
- }
58508
58297
  return queueWalletFetch(async () => {
58509
- const fetched = await wallet.transferService.getTransfersByIds.call(wallet.transferService, transferIds3);
58510
- if (typeof wallet.constructTransfersWithUserRequest === "function") {
58511
- return wallet.constructTransfersWithUserRequest(fetched);
58512
- }
58513
- return Array.isArray(fetched) ? fetched : [];
58298
+ const client = await wallet.connectionManager.createSparkClient(wallet.config.getCoordinatorAddress());
58299
+ const result = await client.query_transfers_by_id({ transferIds: transferIds3, network: wallet.config.getNetworkProto() });
58300
+ return wallet.constructTransfersWithUserRequest(result.transfers);
58514
58301
  });
58515
58302
  };
58516
- const fetchRecentTransferPagesForIds = async (ids, baseTransfers = [], { maxPages = PENDING_TRANSFER_RECONCILE_MAX_PAGES, pageSize = PENDING_TRANSFER_RECONCILE_PAGE_SIZE } = {}) => {
58517
- const requestedIds = uniqueIds(ids);
58518
- if (!requestedIds.length) {
58519
- return { transfers: [], foundIds: [], pages: 0, pageCount: 0 };
58520
- }
58521
- const requestedSet = new Set(requestedIds);
58522
- const baseById = new Map(baseTransfers.map((tx) => [String(tx?.id || ""), tx]));
58523
- const targetTransfers = requestedIds.map((id) => baseById.get(id)).filter(Boolean);
58524
- const oldestTargetMs = getOldestAnyTransferMs(targetTransfers);
58525
- const foundIds = new Set;
58526
- const transfers = [];
58527
- let offset = 0;
58528
- let pages = 0;
58529
- let pageCount = 0;
58530
- while (pages < maxPages && foundIds.size < requestedSet.size) {
58531
- const page = transferPage(await fetchTransfersPage(pageSize, offset), offset, pageSize);
58532
- const pageTransfers = page.transfers;
58533
- pages += 1;
58534
- pageCount += pageTransfers.length;
58535
- transfers.push(...pageTransfers);
58536
- for (const tx of pageTransfers) {
58537
- const id = String(tx?.id || "");
58538
- if (requestedSet.has(id)) {
58539
- foundIds.add(id);
58540
- }
58541
- }
58542
- if (!page.hasMore) {
58543
- break;
58544
- }
58545
- const oldestPageMs = getOldestAnyTransferMs(pageTransfers);
58546
- if (oldestTargetMs != null && oldestPageMs != null && oldestPageMs < oldestTargetMs) {
58547
- break;
58548
- }
58549
- if (page.nextOffset <= offset) {
58550
- break;
58551
- }
58552
- offset = page.nextOffset;
58553
- }
58554
- return { transfers, foundIds: [...foundIds], pages, pageCount };
58555
- };
58556
58303
  const getPendingTransfersSnapshot = () => {
58557
58304
  if (!wallet) {
58558
58305
  return Promise.resolve([]);
@@ -58607,9 +58354,7 @@ function createWalletTransferSession({ wallet, walletPK, claimIncomingTransfers,
58607
58354
  setReady: () => setTxReadyValue(true)
58608
58355
  },
58609
58356
  reads: {
58610
- byId: fetchTransferById,
58611
- byIds: fetchTransfersByIds,
58612
- recentPages: fetchRecentTransferPagesForIds
58357
+ byIds: fetchTransfersByIds
58613
58358
  },
58614
58359
  claims: incomingClaims,
58615
58360
  waitForWork: waitForBackgroundWorkSlot,
@@ -58802,6 +58547,7 @@ function createWalletTransferSession({ wallet, walletPK, claimIncomingTransfers,
58802
58547
  serverHistoryComplete: historyComplete,
58803
58548
  hasMoreTxs: !historyComplete,
58804
58549
  hasPendingTxs,
58550
+ hasRequestedTransfers: pendingReconciliation.hasRequestedTransfers,
58805
58551
  hasPendingIncomingTxs: pendingIncomingTransfers(transfers).length > 0,
58806
58552
  beginSdkActivity,
58807
58553
  getRecentTxs,
@@ -58849,7 +58595,6 @@ function createWalletTransferSession({ wallet, walletPK, claimIncomingTransfers,
58849
58595
  }
58850
58596
 
58851
58597
  // ../../core/wallet/session.js
58852
- var NOOP5 = () => {};
58853
58598
  var ASYNC_NOOP = async () => null;
58854
58599
  var ASYNC_FALSE = async () => false;
58855
58600
  var EMPTY_COVERAGE = async () => ({ loaded: 0, historyComplete: false });
@@ -58902,7 +58647,6 @@ function createEmptyWalletSessionSnapshot(network, transferSnapshot = null, cach
58902
58647
  isWalletDataReady: false,
58903
58648
  isWalletDataLoaded: cachedDataReady || cachedBalance != null,
58904
58649
  refresh: ASYNC_NOOP,
58905
- setTransferDiscoveryVisible: NOOP5,
58906
58650
  claimDeposits: ASYNC_FALSE,
58907
58651
  getFundingAddress: ASYNC_NOOP,
58908
58652
  preparePayment: WALLET_NOT_READY,
@@ -58935,7 +58679,6 @@ function createWalletSession({
58935
58679
  network,
58936
58680
  claimIncomingTransfers = null,
58937
58681
  pendingClaimBatchSize = null,
58938
- activeTransferRefreshMs = null,
58939
58682
  eagerOutgoingStatusRefresh = false,
58940
58683
  sentTransferRefreshDelayMs = null,
58941
58684
  deferBackgroundWork = null,
@@ -58958,7 +58701,7 @@ function createWalletSession({
58958
58701
  let publishedSnapshot = null;
58959
58702
  const valueSubscriptions = createFieldSubscriptions(() => publishedSnapshot?.value);
58960
58703
  const txSubscriptions = createFieldSubscriptions(() => publishedSnapshot?.txValue);
58961
- let polling = null;
58704
+ let reconciliation = null;
58962
58705
  let readyDiag = null;
58963
58706
  let refreshWalletBalance = null;
58964
58707
  const transferSession = createWalletTransferSession({
@@ -58980,7 +58723,7 @@ function createWalletSession({
58980
58723
  return;
58981
58724
  const nextSnapshot = buildSnapshot();
58982
58725
  readyDiag?.sync();
58983
- polling?.sync();
58726
+ reconciliation?.sync();
58984
58727
  if (publishedSnapshot && nextSnapshot.value === publishedSnapshot.value && nextSnapshot.txValue === publishedSnapshot.txValue) {
58985
58728
  return;
58986
58729
  }
@@ -59010,17 +58753,16 @@ function createWalletSession({
59010
58753
  });
59011
58754
  const claims = createDepositClaims({
59012
58755
  wallet,
59013
- updateWalletData,
59014
58756
  diag
59015
58757
  });
59016
- polling = createWalletPolling({
59017
- wallet,
58758
+ reconciliation = createWalletReconciliation({
59018
58759
  network,
59019
58760
  appState,
59020
58761
  getTransferState,
59021
- getBalanceState: balance.getSnapshot,
59022
- refreshClaims: claims.refreshClaims,
59023
- activeTransferRefreshMs,
58762
+ updateWalletData,
58763
+ deferBackgroundWork,
58764
+ backgroundSignal: backgroundAbort.signal,
58765
+ claimDeposits: claims.claimDeposits,
59024
58766
  diag
59025
58767
  });
59026
58768
  readyDiag = createWalletReadyDiag({
@@ -59031,9 +58773,9 @@ function createWalletSession({
59031
58773
  });
59032
58774
  const events = createWalletEvents({
59033
58775
  wallet,
59034
- updateWalletData,
59035
58776
  getTransferState,
59036
- setBalance: balance.setBalance,
58777
+ reconcile: reconciliation.request,
58778
+ sync: reconciliation.sync,
59037
58779
  setTokenBalances: balance.setTokenBalances,
59038
58780
  setSatsBalanceResult: balance.setSatsBalanceResult,
59039
58781
  diag
@@ -59077,8 +58819,7 @@ function createWalletSession({
59077
58819
  isBalanceLoading: balanceState.isBalanceLoading,
59078
58820
  isWalletDataReady: true,
59079
58821
  isWalletDataLoaded: balanceState.balanceReady || currentTransferState.txReady,
59080
- refresh: claims.refresh,
59081
- setTransferDiscoveryVisible: polling.setTransferDiscoveryVisible,
58822
+ refresh: reconciliation.refresh,
59082
58823
  claimDeposits: claims.claimDeposits,
59083
58824
  getFundingAddress: funding.getFundingAddress,
59084
58825
  preparePayment: mutationActions.preparePayment,
@@ -59110,17 +58851,8 @@ function createWalletSession({
59110
58851
  const unsubscribeTransfers = transferSession.subscribe(publish);
59111
58852
  publishedSnapshot = buildSnapshot();
59112
58853
  readyDiag.sync();
59113
- polling.sync();
59114
- const boot = createWalletBoot({
59115
- wallet,
59116
- getTransferState,
59117
- getBalance: balance.getBalance,
59118
- getRecentTxs: transferState.getRecentTxs,
59119
- deferBackgroundWork,
59120
- backgroundSignal: backgroundAbort.signal,
59121
- stopPoll: polling.stopPoll,
59122
- diag
59123
- });
58854
+ reconciliation.sync();
58855
+ reconciliation.start();
59124
58856
  return {
59125
58857
  wallet,
59126
58858
  walletPK,
@@ -59144,9 +58876,8 @@ function createWalletSession({
59144
58876
  return;
59145
58877
  closed = true;
59146
58878
  backgroundAbort.abort();
59147
- boot.close();
59148
58879
  events.close();
59149
- polling.close();
58880
+ reconciliation.close();
59150
58881
  privacy.close();
59151
58882
  mutations.close();
59152
58883
  payment.close();
@@ -59771,7 +59502,7 @@ function getPeerDataFromTransfers(transfers, walletPK, peerPK) {
59771
59502
  txs.sort(byRecentTx);
59772
59503
  return { txs, stats: stats.cnt ? stats : null };
59773
59504
  }
59774
- var NOOP6 = () => {};
59505
+ var NOOP5 = () => {};
59775
59506
  var EMPTY_TX_DATA_SOURCES = Object.freeze({
59776
59507
  balance: null,
59777
59508
  walletPK: null,
@@ -59803,8 +59534,8 @@ function createTxData({ transferStore, historyStore, diag = null, deferAggregati
59803
59534
  let snapshot = null;
59804
59535
  let observedStoreSnapshot = null;
59805
59536
  let observedHistorySnapshot = null;
59806
- let unsubscribeStore = NOOP6;
59807
- let unsubscribeHistory = NOOP6;
59537
+ let unsubscribeStore = NOOP5;
59538
+ let unsubscribeHistory = NOOP5;
59808
59539
  let closed = false;
59809
59540
  function readCurrentAggregatedData(walletPK) {
59810
59541
  const transfers = transferStore.getSnapshot().transfers;
@@ -60139,7 +59870,7 @@ function createTxData({ transferStore, historyStore, diag = null, deferAggregati
60139
59870
  },
60140
59871
  subscribe(listener) {
60141
59872
  if (closed || typeof listener !== "function")
60142
- return NOOP6;
59873
+ return NOOP5;
60143
59874
  if (!listeners.size) {
60144
59875
  if (!deferAggregation) {
60145
59876
  unsubscribeStore = transferStore.subscribe(() => rebuild());
@@ -60159,8 +59890,8 @@ function createTxData({ transferStore, historyStore, diag = null, deferAggregati
60159
59890
  return;
60160
59891
  unsubscribeStore();
60161
59892
  unsubscribeHistory();
60162
- unsubscribeStore = NOOP6;
60163
- unsubscribeHistory = NOOP6;
59893
+ unsubscribeStore = NOOP5;
59894
+ unsubscribeHistory = NOOP5;
60164
59895
  };
60165
59896
  },
60166
59897
  setSources,
@@ -60170,8 +59901,8 @@ function createTxData({ transferStore, historyStore, diag = null, deferAggregati
60170
59901
  closed = true;
60171
59902
  unsubscribeStore();
60172
59903
  unsubscribeHistory();
60173
- unsubscribeStore = NOOP6;
60174
- unsubscribeHistory = NOOP6;
59904
+ unsubscribeStore = NOOP5;
59905
+ unsubscribeHistory = NOOP5;
60175
59906
  listeners.clear();
60176
59907
  seriesCache.current.clear();
60177
59908
  historySeriesCache.current.clear();
@@ -60180,7 +59911,7 @@ function createTxData({ transferStore, historyStore, diag = null, deferAggregati
60180
59911
  }
60181
59912
 
60182
59913
  // src/wallet.js
60183
- var NOOP7 = () => {};
59914
+ var NOOP6 = () => {};
60184
59915
  var ACTIVE_APP_STATE = Object.freeze({
60185
59916
  currentState: "active",
60186
59917
  addEventListener() {
@@ -60232,8 +59963,8 @@ function openWallet(options = {}) {
60232
59963
  let cachedBalance = null;
60233
59964
  let peerCache = { transfers: null, historyGeneration: -1, walletPK: "", value: {} };
60234
59965
  let sessionOwner = null;
60235
- let releaseSessionOwner = NOOP7;
60236
- let stopSessionOwner = NOOP7;
59966
+ let releaseSessionOwner = NOOP6;
59967
+ let stopSessionOwner = NOOP6;
60237
59968
  let snapshot = createEmptyWalletSessionSnapshot(initialNetwork, transferStore.getSnapshot(), null, historyStore.getSnapshot());
60238
59969
  function syncTransactions() {
60239
59970
  transactions.setSources({
@@ -60267,8 +59998,8 @@ function openWallet(options = {}) {
60267
59998
  function detachSessionOwner() {
60268
59999
  const stop = stopSessionOwner;
60269
60000
  const release = releaseSessionOwner;
60270
- stopSessionOwner = NOOP7;
60271
- releaseSessionOwner = NOOP7;
60001
+ stopSessionOwner = NOOP6;
60002
+ releaseSessionOwner = NOOP6;
60272
60003
  sessionOwner = null;
60273
60004
  stop();
60274
60005
  release();
@@ -60284,7 +60015,6 @@ function openWallet(options = {}) {
60284
60015
  network: sources.network,
60285
60016
  claimIncomingTransfers: options.claimIncomingTransfers || claimIncomingTransfersById,
60286
60017
  pendingClaimBatchSize: options.pendingClaimBatchSize,
60287
- activeTransferRefreshMs: options.activeTransferRefreshMs,
60288
60018
  eagerOutgoingStatusRefresh: options.eagerOutgoingStatusRefresh === true,
60289
60019
  sentTransferRefreshDelayMs: options.sentTransferRefreshDelayMs,
60290
60020
  deferBackgroundWork: options.deferBackgroundWork || null,
@@ -60345,7 +60075,7 @@ function openWallet(options = {}) {
60345
60075
  },
60346
60076
  subscribe(listener) {
60347
60077
  if (closed || typeof listener !== "function")
60348
- return NOOP7;
60078
+ return NOOP6;
60349
60079
  listeners.add(listener);
60350
60080
  return () => listeners.delete(listener);
60351
60081
  },
@@ -60508,7 +60238,7 @@ function createAccountOperationCloseBarrier() {
60508
60238
  }
60509
60239
 
60510
60240
  // src/account.js
60511
- var NOOP8 = () => {};
60241
+ var NOOP7 = () => {};
60512
60242
  function vaultPasswordChangeError(code, message, cause = null) {
60513
60243
  const error = new Error(message);
60514
60244
  error.code = `vault-password/${code}`;
@@ -60566,7 +60296,7 @@ function openAccount(options = {}) {
60566
60296
  let closed = false;
60567
60297
  let attempt = 0;
60568
60298
  let foreground = true;
60569
- let stopVault = NOOP8;
60299
+ let stopVault = NOOP7;
60570
60300
  let syncingUser = false;
60571
60301
  let closePromise = null;
60572
60302
  let state;
@@ -60593,7 +60323,7 @@ function openAccount(options = {}) {
60593
60323
  revokedUid = accountUid;
60594
60324
  bootstrapGeneration += 1;
60595
60325
  if (accountUid && options.bootstrapStorage) {
60596
- bootstrapWriteTail = bootstrapWriteTail.catch(NOOP8).then(() => options.bootstrapStorage.remove(accountUid));
60326
+ bootstrapWriteTail = bootstrapWriteTail.catch(NOOP7).then(() => options.bootstrapStorage.remove(accountUid));
60597
60327
  bootstrapWriteTail.catch((error) => diag?.("account.bootstrap.remove.error", { code: error?.code || "" }));
60598
60328
  }
60599
60329
  let callback;
@@ -60979,7 +60709,7 @@ function openAccount(options = {}) {
60979
60709
  }
60980
60710
  function watchVault(uid) {
60981
60711
  stopVault();
60982
- stopVault = NOOP8;
60712
+ stopVault = NOOP7;
60983
60713
  if (!uid)
60984
60714
  return;
60985
60715
  const startedAt = Date.now();
@@ -61057,11 +60787,11 @@ function openAccount(options = {}) {
61057
60787
  bootstrapGeneration += 1;
61058
60788
  lastBootstrap = "";
61059
60789
  if (previousUid && !uid && options.bootstrapStorage) {
61060
- bootstrapWriteTail = bootstrapWriteTail.catch(NOOP8).then(() => options.bootstrapStorage.remove(previousUid));
60790
+ bootstrapWriteTail = bootstrapWriteTail.catch(NOOP7).then(() => options.bootstrapStorage.remove(previousUid));
61061
60791
  bootstrapWriteTail.catch((error) => diag?.("account.bootstrap.remove.error", { code: error?.code || "" }));
61062
60792
  }
61063
60793
  stopVault();
61064
- stopVault = NOOP8;
60794
+ stopVault = NOOP7;
61065
60795
  closeSession({ notify: false });
61066
60796
  user.setNetwork(defaultNetwork);
61067
60797
  const currentUser = user.getSnapshot();
@@ -61126,7 +60856,7 @@ function openAccount(options = {}) {
61126
60856
  lastBootstrap = serialized;
61127
60857
  const uid = state.uid;
61128
60858
  const generation = bootstrapGeneration;
61129
- bootstrapWriteTail = bootstrapWriteTail.catch(NOOP8).then(() => {
60859
+ bootstrapWriteTail = bootstrapWriteTail.catch(NOOP7).then(() => {
61130
60860
  if (closed || generation !== bootstrapGeneration || state.uid !== uid)
61131
60861
  return;
61132
60862
  return options.bootstrapStorage.write(uid, value);
@@ -61551,7 +61281,7 @@ function openAccount(options = {}) {
61551
61281
  getSnapshot: () => state,
61552
61282
  subscribe(listener) {
61553
61283
  if (typeof listener !== "function")
61554
- return NOOP8;
61284
+ return NOOP7;
61555
61285
  listeners.add(listener);
61556
61286
  return () => listeners.delete(listener);
61557
61287
  },