Skip to content

Fix wallet connect performance with bounded address data fetching#758

Merged
jamespepper81 merged 4 commits into
mainfrom
dev
May 29, 2026
Merged

Fix wallet connect performance with bounded address data fetching#758
jamespepper81 merged 4 commits into
mainfrom
dev

Conversation

@jamespepper81
Copy link
Copy Markdown
Contributor

No description provided.

claude and others added 4 commits May 29, 2026 08:37
The fresh-connect path (getWalletDataProgressive) fetched per-address
data inside discovery's onAddressFound callback, which was invoked
without await. This fired 3 Esplora calls per address with unbounded
concurrency, flooding the provider (429/5xx -> retry-backoff) and
racing the snapshot build so the last-discovered addresses' data could
be dropped. For wallets with many addresses this stretched the
connect->dashboard flow into minutes.

Changes:
- Extract the bounded worker-queue (concurrency 6) from
  fetchWalletSnapshot into a shared fetchAddressDataConcurrent helper;
  refactor fetchWalletSnapshot to use it.
- Progressive discovery now only COLLECTS addresses (plus the /address
  stats already fetched during discovery); heavy /txs + /utxo fetching
  runs afterwards via the bounded pool and is awaited before building
  the snapshot, removing both the flood and the race.
- Reuse discovery stats as the address `info`, skipping a redundant
  /address call per address.
- Restore live progress: emit discovery-phase counts (skeleton keeps
  showing "Found N addresses") and stream real data during the fetch
  phase. Guard the wallet-context handler so empty discovery-phase
  updates don't clobber the loading skeleton.
- Wrap progressive discovery in the 4-minute discovery timeout for
  parity with the cached path.
- Bump PARALLEL_BATCH_SIZE to 20 so a full gap window resolves in one
  parallel round-trip.

Adds behavioral tests for the bounded fetcher (concurrency cap, race
fix, stats reuse, utxo retry) and source-level regression guards.

https://claude.ai/code/session_013r8mPRVH2dz81nP9VBm8uC
mock.calls is typed any[][]; the destructured [path]: [string]
parameter annotation didn't satisfy the filter overload, failing
the CI typecheck step. Index the call args directly instead.

https://claude.ai/code/session_013r8mPRVH2dz81nP9VBm8uC
Code review of the progressive-connect change surfaced three issues:

1. (Bug) Discovery fires a final onBatchComplete with isComplete:true
   when address discovery ends - but the heavy per-address fetch still
   follows. emitDiscoveryProgress forwarded that as an empty-data
   isComplete:true update, so the dashboard dropped its loading state
   and showed a zero-balance wallet (clobbering any cached snapshot
   already on screen) before real data arrived. Discovery-phase emits
   now force isComplete:false; only the genuine final update completes.

2. (Hardening) Added a receivedComplete latch in the wallet-context
   onProgress handler so a late or out-of-order partial emit can't
   revert a finished dashboard back to a partial view.

3. (Efficiency) Hoisted `new Set(usedAddresses)` out of the per-tx map
   in buildPartialWalletData; it was rebuilt for every transaction, and
   that function now runs repeatedly as data streams in during connect.

Adds a regression guard that discovery-phase emits never report
isComplete:true.

https://claude.ai/code/session_013r8mPRVH2dz81nP9VBm8uC
Fix wallet connect performance regression with bounded address data fetching
@jamespepper81 jamespepper81 merged commit e653c2d into main May 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants