Skip to content

fix(sdk): correct account-history pagination and stop dropping requested ops - #1396

Merged
feruzm merged 3 commits into
developfrom
fix/sdk-account-history-pagination
Aug 11, 2026
Merged

fix(sdk): correct account-history pagination and stop dropping requested ops#1396
feruzm merged 3 commits into
developfrom
fix/sdk-account-history-pagination

Conversation

@feruzm

@feruzm feruzm commented Aug 11, 2026

Copy link
Copy Markdown
Member

SDK follow-ups for the mobile wallet history fix (ecency/vision-mobile#3480). Needs an @ecency/sdk release before that PR merges, so mobile can drop its local workarounds.

Everything here was checked against every web consumer first. Web behaviour is unchanged except where it was already broken.

1. getNextPageParam read the wrong end of the page

condenser_api.get_account_history returns each page in ascending num order, so index 0 is the oldest row. The cursor used lastPage[lastPage.length - 1] — the newest row — so each page advanced the window by a single operation. Verified live at limit 50 on good-karma:

page 1: num 8842005 … 8842054
cursor: 8842053     (should be 8842004)
page 2: num 8842004 … 8842053   -> 49 of 50 rows duplicated

The web wallet pages use limit: 1000, so every "load more" re-fetched 999 rows it already had. At the start of history the cursor produced -1, which is initialPageParam (the "give me the newest" sentinel), so the walk restarted at the head and never terminated — hasNextPage was permanently true.

Now page[0].num - 1, terminating at 0 and on an empty page. Empty is the real terminal condition: with a narrow operation filter the node returns the newest N matches and then [], and a short page does not mean the end (measured: a 20-row page followed by more history), so the cursor keys off num, never page length.

2. The per-asset select discarded operations the caller asked for

HIVE and HBD ended in default: return false, dropping any operation the switch has no opinion about even when it was explicitly requested and paid for over the wire. The wallet filter dropdown is built from HIVE_OPERATION_LIST (every operation name), so picking one outside the switch — fill_transfer_from_savings, escrow_* — silently returned an empty list.

The default now keeps operations the caller named explicitly. Requests that pass no filter still fall through to false, so the unfiltered HIVE/HBD views are unchanged; only an explicit pick behaves differently. HP already worked this way and is untouched.

3. fill_transfer_from_savings was never fetched

ACCOUNT_OPERATION_GROUPS.transfers listed fill_recurrent_transfer twice and omitted op 59, so a completed savings withdrawal never came back from the transfers group or from ALL_ACCOUNT_OPERATIONS. Replaced the duplicate with 59 and de-duplicated ALL_ACCOUNT_OPERATIONS (groups overlap, and the raw concatenation repeated ids in hafah's operation-types query string).

producer_reward deliberately stays in the group-less default — features/shared/transactions/transaction-row.tsx renders it, and dropping it would silently empty the profile transactions list for witnesses.

4. initialData removed from the HIVE options (inherited by HBD/HP)

initialData: { pages: [], pageParams: [] } only ever suited a server-prefetched page. Any client with a non-zero default staleTime reads that empty seed as fresh data and skips the first fetch entirely.

Safe for web, checked: these queries are never prefetchInfiniteQuery'd on the server, core/react-query sets staleTime: 60_000, useInfiniteDataFlow already handles undefined, and the useMount(() => refetch()) on each wallet token page (which was covering for this) still fires.

Web changes

Only what's needed so the newly-returned operation renders instead of hitting the raw-JSON fallback:

  • TransferFromSavings + FillTransferFromSavings added to the SDK Transaction union, and FillTransferFromSavings to apps/web/src/entities/hive/transaction.ts. The two unions must stay structurally identical or the SDK type stops being assignable to the web one — that is what request_id: number (required, matching the chain and the existing web type) is about.
  • A fill_transfer_from_savings branch in the shared transaction row and in the HIVE/HBD wallet rows.
  • transactions.type-fill_transfer_from_savings in en-US.

Verification

  • pnpm --filter @ecency/sdk test — 700 passed (49 files), including a new account-history-pagination.spec.ts covering cursor direction, termination at num === 0 and on an empty page, no self-overlap, the filter-collection semantics, and the ALL_ACCOUNT_OPERATIONS invariants (deduped, contains 59, still contains producer_reward).
  • pnpm --filter @ecency/web test — 2580 passed (269 files).
  • apps/web tsc --noEmit — 0 errors, same as develop.
  • pnpm --filter @ecency/sdk lint and web lint — clean (web shows only pre-existing spec warnings).
  • apps/self-hosted does not import any of these queries; its one tsc error is pre-existing on develop (missing generated config.json).

dist/ is intentionally not rebuilt here — that is label-gated.

Not addressed

hafah's /accounts/{name}/operations returns the remainder bucket when page is omitted (its pages run oldest-first, and the spec has no order parameter), so the first page of the profile transactions list is total_operations mod page-size rows — as few as 1. Fixing it needs a second round trip to learn total_pages, so it is left alone here.

…ted ops

Three defects in the account/asset transaction queries, found while fixing the
mobile wallet's HIVE/HBD history (ecency/vision-mobile#3480).

**1. getNextPageParam read the wrong end of the page.**
`condenser_api.get_account_history` returns each page in ASCENDING `num` order,
so index 0 is the OLDEST row. The cursor used `lastPage[lastPage.length - 1]`,
the NEWEST row, which advanced the window by a single operation per page: at the
web wallet's limit of 1000 each "load more" re-fetched 999 rows it already had
(verified live at limit 50: pages 1 and 2 overlapped by 49 of 50). At the start
of history it produced `-1`, which is `initialPageParam` -- the "give me the
newest" sentinel -- so the walk restarted at the head and never terminated.

Now `page[0].num - 1`, terminating at 0 and on an empty page. An empty page is
the real terminal condition: with a narrow operation filter the node returns the
newest N matches and then `[]`, and a short page does not mean the end, so the
cursor keys off `num` rather than page length.

**2. The per-asset `select` discarded operations the caller asked for.**
HIVE and HBD ended in `default: return false`, so any operation the switch has no
opinion about was dropped even when explicitly requested. The wallet filter
dropdown is built from HIVE_OPERATION_LIST (every operation name), so picking one
outside the switch -- `fill_transfer_from_savings`, `escrow_*` -- returned an
empty list. The default now keeps operations the caller named. Requests that pass
no filter still fall through to `false`, so the unfiltered HIVE/HBD views are
byte-for-byte unchanged; HP already behaved this way and is untouched.

**3. `fill_transfer_from_savings` was never fetched.**
ACCOUNT_OPERATION_GROUPS.transfers listed `fill_recurrent_transfer` twice and
omitted op 59, so a completed savings withdrawal never came back from the
transfers group or from ALL_ACCOUNT_OPERATIONS. Replaced the duplicate with 59
and de-duplicated ALL_ACCOUNT_OPERATIONS (groups overlap, and the raw
concatenation repeated ids in hafah's `operation-types` query string).
`producer_reward` deliberately stays in the default -- the web profile
transactions list renders it.

Also removes `initialData: { pages: [], pageParams: [] }` from the HIVE options
(inherited by HBD and HP). It only ever suited a server-prefetched page: any
client with a non-zero default `staleTime` reads that empty seed as fresh data
and skips the first fetch entirely. Web sets `staleTime: 60_000` and does not
prefetch these on the server -- the `useMount(() => refetch())` on each wallet
token page is what was covering for it -- and `useInfiniteDataFlow` already
handles `undefined`, so web is unaffected.

Web side, so the newly-returned op renders instead of falling back to raw JSON:
adds `TransferFromSavings`/`FillTransferFromSavings` to the SDK Transaction union
and `FillTransferFromSavings` to the web entity union (they must stay
structurally identical), a `fill_transfer_from_savings` branch in the shared
transaction row and the HIVE/HBD wallet rows, and the en-US string.

pnpm --filter @ecency/sdk test: 700 passed. @ecency/web test: 2580 passed.
apps/web tsc --noEmit: 0 errors, same as develop.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@feruzm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 4 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e074edf9-f893-4540-8c05-e9f13308e5a1

📥 Commits

Reviewing files that changed from the base of the PR and between c082694 and 6cec2eb.

⛔ Files ignored due to path filters (7)
  • packages/sdk/dist/browser/index.d.ts is excluded by !**/dist/**
  • packages/sdk/dist/browser/index.js is excluded by !**/dist/**
  • packages/sdk/dist/browser/index.js.map is excluded by !**/dist/**, !**/*.map
  • packages/sdk/dist/node/index.cjs is excluded by !**/dist/**
  • packages/sdk/dist/node/index.cjs.map is excluded by !**/dist/**, !**/*.map
  • packages/sdk/dist/node/index.mjs is excluded by !**/dist/**
  • packages/sdk/dist/node/index.mjs.map is excluded by !**/dist/**, !**/*.map
📒 Files selected for processing (14)
  • apps/web/src/app/(dynamicPages)/profile/[username]/wallet/(token)/hbd/_components/hive-transaction-row.tsx
  • apps/web/src/app/(dynamicPages)/profile/[username]/wallet/(token)/hive/_components/hive-transaction-row.tsx
  • apps/web/src/entities/hive/transaction.ts
  • apps/web/src/features/i18n/locales/en-US.json
  • apps/web/src/features/shared/transactions/transaction-row.tsx
  • packages/sdk/CHANGELOG.md
  • packages/sdk/package.json
  • packages/sdk/src/modules/accounts/queries/get-transactions-infinite-query-options.ts
  • packages/sdk/src/modules/accounts/types/transaction.ts
  • packages/sdk/src/modules/wallet/queries/account-history-pagination.spec.ts
  • packages/sdk/src/modules/wallet/queries/get-hbd-asset-transactions-query-options.ts
  • packages/sdk/src/modules/wallet/queries/get-hive-asset-transactions-query-options.ts
  • packages/wallets/CHANGELOG.md
  • packages/wallets/package.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@feruzm feruzm added the patch Bug fixes and patches (1.0.0 → 1.0.1) label Aug 11, 2026
github-actions Bot and others added 2 commits August 11, 2026 11:40
Resolves the version collision introduced by the label-triggered changeset run:
both this branch and #1394 on develop bumped @ecency/sdk to 2.3.79, and 2.3.79
is already published to npm, so merging as-is would have failed `publish:sdk`.

- packages/sdk/CHANGELOG.md: keep develop's 2.3.79 entry, move this PR's entry to
  a new 2.3.80 section.
- @ecency/sdk 2.3.79 -> 2.3.80, @ecency/wallets 5.0.79 -> 5.0.80 (dependent bump),
  with the matching wallets CHANGELOG entry.
- packages/sdk/dist: regenerated from the merged source rather than hand-merged.
  Verified the bundle carries both sides — this branch's account-history changes
  and develop's quests catalog.

@ecency/sdk test 706 passed, @ecency/web test 2590 passed, apps/web tsc --noEmit
0 errors.
@feruzm
feruzm merged commit 496896a into develop Aug 11, 2026
12 checks passed
@feruzm
feruzm deleted the fix/sdk-account-history-pagination branch August 11, 2026 11:53
feruzm added a commit to ecency/vision-mobile that referenced this pull request Aug 11, 2026
… override

2.3.80 (ecency/vision-web#1396) carries the account-history fixes this branch was
working around:

- The cursor now walks back from the OLDEST row on the page, so the local
  `getNextPageParam` override is redundant. Removed it, along with
  `getNextHistoryPageParam` and its tests -- the SDK owns and tests that contract
  now, and a second copy here could silently override a future SDK change.
- The per-asset `select` no longer discards operations the caller asked for by
  name, and `fill_transfer_from_savings` is back in the transfers group, so it is
  finally requestable. Added it to the HIVE/HBD set: `transferTypes` and
  `groomingTransactionData` already render it, so a completed savings withdrawal
  now shows up in the history instead of never arriving.

`initialData: undefined` stays. 2.3.80 removed the seed, but no SDK test pins its
absence and the failure it causes is invisible -- an empty list for the length of
staleTime, with no error -- so it is worth keeping as a guard. Comment reworded to
say so.

yarn typecheck clean, yarn test:ci 812 passed / 1 skipped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch Bug fixes and patches (1.0.0 → 1.0.1)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant