fix(sdk): correct account-history pagination and stop dropping requested ops - #1396
Conversation
…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.
|
Warning Review limit reached
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 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (7)
📒 Files selected for processing (14)
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. Comment |
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.
… 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.
SDK follow-ups for the mobile wallet history fix (ecency/vision-mobile#3480). Needs an
@ecency/sdkrelease 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.
getNextPageParamread the wrong end of the pagecondenser_api.get_account_historyreturns each page in ascendingnumorder, so index 0 is the oldest row. The cursor usedlastPage[lastPage.length - 1]— the newest row — so each page advanced the window by a single operation. Verified live at limit 50 ongood-karma: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 isinitialPageParam(the "give me the newest" sentinel), so the walk restarted at the head and never terminated —hasNextPagewas 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 offnum, never page length.2. The per-asset
selectdiscarded operations the caller asked forHIVE 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 fromHIVE_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_savingswas never fetchedACCOUNT_OPERATION_GROUPS.transferslistedfill_recurrent_transfertwice and omitted op 59, so a completed savings withdrawal never came back from the transfers group or fromALL_ACCOUNT_OPERATIONS. Replaced the duplicate with 59 and de-duplicatedALL_ACCOUNT_OPERATIONS(groups overlap, and the raw concatenation repeated ids in hafah'soperation-typesquery string).producer_rewarddeliberately stays in the group-less default —features/shared/transactions/transaction-row.tsxrenders it, and dropping it would silently empty the profile transactions list for witnesses.4.
initialDataremoved from the HIVE options (inherited by HBD/HP)initialData: { pages: [], pageParams: [] }only ever suited a server-prefetched page. Any client with a non-zero defaultstaleTimereads 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-querysetsstaleTime: 60_000,useInfiniteDataFlowalready handlesundefined, and theuseMount(() => 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+FillTransferFromSavingsadded to the SDKTransactionunion, andFillTransferFromSavingstoapps/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 whatrequest_id: number(required, matching the chain and the existing web type) is about.fill_transfer_from_savingsbranch in the shared transaction row and in the HIVE/HBD wallet rows.transactions.type-fill_transfer_from_savingsin en-US.Verification
pnpm --filter @ecency/sdk test— 700 passed (49 files), including a newaccount-history-pagination.spec.tscovering cursor direction, termination atnum === 0and on an empty page, no self-overlap, the filter-collection semantics, and theALL_ACCOUNT_OPERATIONSinvariants (deduped, contains 59, still containsproducer_reward).pnpm --filter @ecency/web test— 2580 passed (269 files).apps/webtsc --noEmit— 0 errors, same asdevelop.pnpm --filter @ecency/sdk lintand web lint — clean (web shows only pre-existing spec warnings).apps/self-hosteddoes not import any of these queries; its onetscerror is pre-existing ondevelop(missing generatedconfig.json).dist/is intentionally not rebuilt here — that is label-gated.Not addressed
hafah's
/accounts/{name}/operationsreturns the remainder bucket whenpageis omitted (its pages run oldest-first, and the spec has no order parameter), so the first page of the profile transactions list istotal_operations mod page-sizerows — as few as 1. Fixing it needs a second round trip to learntotal_pages, so it is left alone here.