fix(frontend): keep scrolled-in transaction history across the periodic refresh - #13732
Merged
sbpublic merged 4 commits intoAug 14, 2026
Merged
Conversation
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>
|
✅ No security or compliance issues detected. Reviewed everything up to c5c6a6d. Security Overview
Detected Code Changes
|
Contributor
There was a problem hiding this comment.
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
updateOnlyflag, 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.
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>
…ttps://github.com/dfinity/oisy-wallet into fix/frontend/eth-transactions-refresh-keeps-pages
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>
DenysKarmazynDFINITY
approved these changes
Aug 14, 2026
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
batchLoadTransactionscallsloadEthereumTransactionswithoutupdateOnly, so the 30-secondWALLET_TIMER_INTERVAL_MILLIStick runs the full load and ends inethTransactionsStore.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
prependalready deduplicates by hash, and on a first load the slot is empty, so it behaves exactly likesetdid.updateOnly. The timer path is notupdateOnly, 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 wasupdateOnlywas simply wrong.Only the native path changes. ERC token history is still fetched in full, so its
setstays 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.updateOnlyreload 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 acrosstests/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)