Skip to content

fix(frontend): keep scrolled-in transaction history across the periodic refresh - #13732

Merged
sbpublic merged 4 commits into
mainfrom
fix/frontend/eth-transactions-refresh-keeps-pages
Aug 14, 2026
Merged

fix(frontend): keep scrolled-in transaction history across the periodic refresh#13732
sbpublic merged 4 commits into
mainfrom
fix/frontend/eth-transactions-refresh-keeps-pages

Conversation

@sbpublic

@sbpublic sbpublic commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Motivation

Scroll a native EVM token view back through its history, then wait: after about 30 seconds the list snaps back to the newest page, and scrolling down re-fetches everything again. Reproducible on main.

A regression from #13728, which wired up paging without noticing that the refresh timer takes the same code path.

batchLoadTransactions calls loadEthereumTransactions without updateOnly, so the 30-second WALLET_TIMER_INTERVAL_MILLIS tick runs the full load and ends in ethTransactionsStore.set(...). Since #12193 made the native load incremental, that batch is not the whole history — it is the newest stored page (ten rows) plus anything newer than it. Replacing the token's slot with it discards every older page the user scrolled in.

ERC20 views were unaffected only because their history is still fetched whole, so setting the slot there is a genuine refresh.

Changes

  • Prepend the batch instead of setting it. A refresh updates the head and leaves the tail alone. prepend already deduplicates by hash, and on a first load the slot is empty, so it behaves exactly like set did.
  • Key the pagination-cursor reset on the list being empty, not on updateOnly. The timer path is not updateOnly, so the cursor was also being rewound to the second page every 30 seconds — the next scroll then re-walked pages already in the store. The comment in fix(frontend): show ETH and EVM transaction history beyond the newest page #13728 claiming the timer was updateOnly was simply wrong.

Only the native path changes. ERC token history is still fetched in full, so its set stays correct — until #13730 makes that path incremental too, at which point it needs the same treatment.

Tests

  • eth-transactions.services.spec.ts — a refresh keeps pages already scrolled in (the regression itself), and the cursor is left alone once the list has been built. The pre-existing cursor test for a fresh load still holds. The two sets of rows carry fixed, disjoint hashes rather than the mock's random ones, since the store deduplicates by hash and the exact-length assertion would otherwise rest on them never colliding.
  • The updateOnly reload test that asserted the cursor was untouched has been rewritten: it passed for the wrong reason — an empty store, not the reload flag.
  • npm run format, npm run lint -- --max-warnings 0, npm run check (0 errors), npm run check:tests (0 errors), 3848 tests pass across tests/eth.

Diagnosed statically from the symptom (30s, ten surviving rows, native-only) and confirmed by the reporter on main; not re-verified in a browser here.


🤖 Generated with Claude Code — Claude Opus 5 (claude-opus-5)

Scrolling a native EVM token view back through its history, then waiting, threw
the list away: after ~30 seconds it snapped back to the newest page and
scrolling re-fetched everything again.

The refresh timer goes through `loadEthereumTransactions` without `updateOnly`,
which ended in `ethTransactionsStore.set` - and since the load became
incremental, that batch is not the whole history but the newest stored page plus
anything newer. Replacing the slot with it dropped every older page.

Two changes:

- prepend the batch instead of setting it, so a refresh updates the head and
  leaves the tail alone; `prepend` already deduplicates by hash.
- key the pagination-cursor reset on the list being empty rather than on
  `updateOnly`. The timer path is not `updateOnly`, so the cursor was being
  rewound to the second page every 30 seconds as well - the comment claiming
  otherwise was wrong.

Only the native path is affected: ERC token history is still fetched whole, so
setting the slot there is a real refresh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sbpublic added a commit that referenced this pull request Aug 14, 2026
…resh

Same defect #13732 fixes on the native path, which this PR would otherwise
reintroduce for ERC20: once a token's load is incremental, the batch is the
newest stored page plus anything newer, so replacing the store slot with it
discards every older page the user scrolled in - and the refresh timer runs
this path every 30 seconds.

Prepend for a cached token; keep replacing for collectibles, whose history is
still fetched whole, so there the replacement is a real refresh. The cursor
reset is keyed on the list being empty rather than on `updateOnly`, since the
timer path is not `updateOnly`.

The `hasStoredEthTransactions` helper is deliberately written to match #13732
byte for byte: when main is merged in, check it did not land twice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sbpublic
sbpublic marked this pull request as ready for review August 14, 2026 13:45
@sbpublic
sbpublic requested a review from a team as a code owner August 14, 2026 13:45
Copilot AI lite review requested due to automatic review settings August 14, 2026 13:45
@zeropath-ai

zeropath-ai Bot commented Aug 14, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to c5c6a6d.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/frontend/src/eth/services/eth-transactions.services.ts
      Add hasStoredEthTransactions helper and adjust loadEthTransactions behavior to preserve scroll position and prepend new transactions
► src/frontend/src/tests/eth/services/eth-transactions.services.spec.ts
      Update tests to reflect new behavior: keep backend cursor when list built and ensure refresh preserves scrolled pages

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression in the EVM native-asset transaction history where the periodic refresh (timer tick) replaced the store slot with only the newest incremental batch, discarding older pages the user had already paged in and rewinding the backend pagination cursor.

Changes:

  • Native EVM loads now prepend the refreshed batch to preserve already-scrolled history instead of replacing the entire in-memory list.
  • Backend pagination cursor reset is now keyed off the list being empty (initial build) rather than the updateOnly flag, preventing timer-driven cursor rewinds.
  • Tests updated to cover “refresh preserves paged-in rows” and “cursor remains unchanged once the list is built”.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/frontend/src/tests/eth/services/eth-transactions.services.spec.ts Updates/extends unit tests to assert that periodic refresh keeps previously paged-in transaction rows and doesn’t rewind the cursor.
src/frontend/src/eth/services/eth-transactions.services.ts Adjusts native ETH/EVM transaction refresh behavior to prepend incremental batches and avoid resetting the backend pagination cursor once the list is populated.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

sbpublic and others added 2 commits August 14, 2026 16:00
The store deduplicates by hash, so the exact-length assertion was relying on
`createMockEthTransactions` never drawing the same random hash for both sets.

Raised by Copilot on #13732.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sbpublic added a commit that referenced this pull request Aug 14, 2026
The store deduplicates by hash, so the exact-length assertion was relying on
`createMockEthTransactions` never drawing the same random hash for both sets.

Same change as on #13732, which Copilot raised it on; this PR carries the ERC20
twin of that test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sbpublic
sbpublic added this pull request to the merge queue Aug 14, 2026
Merged via the queue into main with commit 0589e58 Aug 14, 2026
88 checks passed
@sbpublic
sbpublic deleted the fix/frontend/eth-transactions-refresh-keeps-pages branch August 14, 2026 14:25
sbpublic added a commit that referenced this pull request Aug 14, 2026
…end/erc20-cache-and-paging

Brings in #13732 via main. One conflict: the store-max helper, renamed here to
`maxBlockNumberInStore` because it now serves the ERC path as well as the
native one. Kept this branch's name.

`hasStoredEthTransactions` was written to match #13732 byte for byte and git
collapsed the two into one, as intended - verified there is exactly one
declaration and no stale references to the old helper name.
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.

3 participants