Skip to content

SDK hardening: rebalance reads, exposure/fee contracts, governance state derivation - #27

Merged
lcamargof merged 19 commits into
mainfrom
sdk/hardening
Jul 23, 2026
Merged

SDK hardening: rebalance reads, exposure/fee contracts, governance state derivation#27
lcamargof merged 19 commits into
mainfrom
sdk/hardening

Conversation

@lcamargof

@lcamargof lcamargof commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

SDK-side hardening changes backing the register hardening effort.

Rebalance

  • Completed-rebalance detail read works end-to-end (Z30) via mapper support.
  • Golden openAuction calldata integration test; unmocked zero-price/supply coverage.
  • Rebalance types extended for the completed-rebalance path.

Index DTF data contracts

  • Type the exposure API contract (ytd period, underlyingMarketCap, native/bridge), dropping the need for consumer casts.
  • Platform fee fails loud on a zero denominator instead of returning a fabricated value.
  • Price-history interval accepts 5m for the 24h chart granularity.

Governance

  • Strict-majority tie semantics and yield-list state derivation.
  • Derive stale-PENDING outcomes past deadline using the chain timepoint rather than wall-clock.

Includes accompanying unit tests and a changeset.

Summary by CodeRabbit

  • New Features

    • Added Index DTF account-balance snapshots, price-at-mark selection, performance composition, and 5-minute price-history intervals.
    • Added typed exposure metadata, year-to-date support, rebalance analytics, and improved brand data normalization.
    • Added synchronous catalog-based single-DTF status lookup and React hooks for snapshots, performance, and price-history prefetching.
    • Added Yield DTF proposal-state derivation, including quorum and strict tie handling.
  • Bug Fixes

    • Corrected stale proposal outcomes, rebalance detail handling, and invalid zero-denominator fee responses.
  • Documentation

    • Expanded SDK and React SDK usage guidance.

…ivation; test(rebalance): unmocked zero-price/supply + golden openAuction calldata
…imepoint over wall clock

- a PENDING proposal past its deadline resolves to the vote/quorum outcome
  like stale ACTIVE (OZ Governor.state() semantics) — never EXPIRED
- getYieldDtfProposals reads one latest block per request and derives
  Anastasius from block.timestamp, Alexios from block.number; the consumer
  machine's clock is never consulted
A zero denominator is an impossible fee tuple, not a 0% fee (numerator=0 over a
positive denominator is the real 0%). Mapping it to percent:0 fabricated a
confident 0% for an invalid registry response — the same class as a fabricated
50%. Now throws INVALID_RESPONSE so consumers render 'unavailable'.
…ngMarketCap, native/bridge)

The exposure endpoint (which Register consumes) returned ytd data, per-token
underlyingMarketCap, and typed native/bridge metadata, but the SDK types
declared period without ytd, omitted underlyingMarketCap, and left native/bridge
as unknown — forcing consumers to cast. Types now match the response; fixture
pins the fields.
…ularity)

The /historical/dtf endpoint serves 5m data for the 24h range, but the interval
union only declared 1h|1d, forcing consumers to cast. Widened both the public
param and the API-layer types; fixture pins the 5m passthrough.
The Reserve API /dtf/rebalance nonce query returns a single-element ARRAY, not an
object (verified against api.reserve.org, base/lcap nonces 1-5). getCompletedRebalance
read it as an object, so the mapper received the array, .auctions was undefined, and
it threw INVALID_RESPONSE on every real response — the read was broken end-to-end,
unnoticed because it had no consumer. Fixes:

- Normalize the single-element-array envelope inside the client api method
  (getIndexDtfRebalanceDetail stays singular); throw RECORD_NOT_FOUND on empty.
- Complete IndexDtfCompletedRebalanceDetail with the analytics fields the detail
  surface renders (avgPriceImpactPercent, totalPriceImpactUsd, marketCapRebalanceImpact,
  tracking/nativeBasketDeviation) so consumers can drop the raw /dtf/rebalance fetch.
- Keep the mapper fail-loud on a truly-absent auctions field: auctions is always
  present ([] when none ran), so absence is malformed, not '0 auctions'.

Tests: array-unwrap + not-found (api), singular map (index), normal/present-empty/
malformed (mappers).
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: b961cb8a-2af1-4095-aaa1-bfe6212dc5bd

📥 Commits

Reviewing files that changed from the base of the PR and between 3b0fbfb and bccf54e.

📒 Files selected for processing (2)
  • apps/docs/src/pages/react-sdk/index-dtf-hooks.mdx
  • docs/wiki/domains/sdk.md
📝 Walkthrough

Walkthrough

This PR updates SDK governance state derivation, rebalance and exposure contracts, account snapshot and performance APIs, catalog-backed status lookups, normalized brand data, React hooks, release validation, licensing, and related documentation.

Changes

Governance state derivation

Layer / File(s) Summary
Proposal state rules and validation
packages/sdk/src/index-dtf/governance/*, packages/sdk/src/yield-dtf/*
Proposal ties resolve as DEFEATED; stale proposals derive terminal states from votes and quorum; Yield DTF lists use governor-native chain timepoints.
Governance documentation and release metadata
.changeset/*governance*, docs/wiki/*
Changesets and wiki records document governance semantics, verification, and deferred findings.

Rebalance and SDK data contracts

Layer / File(s) Summary
Rebalance detail and auction validation
packages/sdk/src/client/api/*, packages/sdk/src/index-dtf/rebalance/*, packages/sdk/src/types/api.ts
Rebalance detail arrays are normalized, empty results raise RECORD_NOT_FOUND, auctions are required, analytics are mapped, and open-auction guards/calldata are tested.
Exposure, price history, and platform fees
packages/sdk/src/index-dtf/dtf/{exposure,platform-fee,price-history}.*, packages/sdk/src/types/*, .changeset/*
Exposure metadata and intervals are typed, five-minute history is supported, and zero-denominator fees raise INVALID_RESPONSE.

Account and display APIs

Layer / File(s) Summary
Account snapshots and performance
packages/sdk/src/index-dtf/dtf/account-pnl.*, packages/react-sdk/src/{hooks.ts,index-dtf/*,query-keys.ts}
Account snapshots, mark-price selection, prefetching, and raw-cache-preserving performance composition are added.
Catalog-backed status
packages/sdk/src/index-dtf/dtf/{status,discovery,index,namespace,ref}.*, packages/react-sdk/src/*status*, packages/react-sdk/src/index-dtf-query-options.ts
Single-DTF status becomes synchronous and catalog-backed, while bulk discovery remains API-backed; React Query status helpers and keys are removed.
Display-ready brand shape
packages/sdk/src/types/index-dtf.ts, packages/sdk/src/index-dtf/dtf/{mappers,index}.ts
Brand types and mappings provide required nested fields, normalized defaults, constrained basket types, and always-present profiles/socials.

Release validation and documentation

Layer / File(s) Summary
Release and publication checks
.github/workflows/*, package.json, README.md, LICENSE, packages/*/LICENSE
CI adds GraphQL codegen validation, publication uses the unified release check, scripts are expanded, and MIT license files are present.
SDK and React SDK surface documentation
apps/docs/*, docs/*, packages/react-sdk/README.md, docs/wiki/*
Documentation distinguishes synchronous catalog status, bulk discovery, snapshots, performance composition, query behavior, and release freshness checks.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise, specific, and clearly reflects the main SDK hardening work across rebalance, exposure/fee, and governance changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sdk/hardening

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/sdk/src/index-dtf/dtf/exposure.test.ts`:
- Around line 13-20: Run oxfmt across the affected test files and commit the
resulting formatting changes: format the long object literals in
packages/sdk/src/index-dtf/dtf/exposure.test.ts lines 13-20,
packages/sdk/src/index-dtf/dtf/price-history.test.ts lines 16-18, and
packages/sdk/src/index-dtf/dtf/platform-fee.test.ts lines 12-18 so the oxfmt
check passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cc8def9e-e80d-485c-af38-a4f592bece11

📥 Commits

Reviewing files that changed from the base of the PR and between 588954e and 7480fb2.

📒 Files selected for processing (25)
  • .changeset/strict-tie-semantics.md
  • docs/wiki/domains/sdk.md
  • docs/wiki/log.md
  • docs/wiki/progress.md
  • packages/sdk/src/client/api.test.ts
  • packages/sdk/src/client/api/index.ts
  • packages/sdk/src/index-dtf/dtf/exposure.test.ts
  • packages/sdk/src/index-dtf/dtf/exposure.ts
  • packages/sdk/src/index-dtf/dtf/platform-fee.test.ts
  • packages/sdk/src/index-dtf/dtf/platform-fee.ts
  • packages/sdk/src/index-dtf/dtf/price-history.test.ts
  • packages/sdk/src/index-dtf/governance/utils.test.ts
  • packages/sdk/src/index-dtf/governance/utils.ts
  • packages/sdk/src/index-dtf/rebalance/index.test.ts
  • packages/sdk/src/index-dtf/rebalance/mappers.test.ts
  • packages/sdk/src/index-dtf/rebalance/mappers.ts
  • packages/sdk/src/index-dtf/rebalance/open-auction.integration.test.ts
  • packages/sdk/src/index-dtf/rebalance/types.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/types/api.ts
  • packages/sdk/src/types/index-dtf.ts
  • packages/sdk/src/types/yield-dtf.ts
  • packages/sdk/src/yield-dtf/governance.test.ts
  • packages/sdk/src/yield-dtf/governance.ts
  • packages/sdk/src/yield-dtf/index.ts

Comment thread packages/sdk/src/index-dtf/dtf/exposure.test.ts
…te outcome, never EXPIRED

FolioGovernor.state() never returns Expired for an unqueued proposal — past
the deadline it derives Defeated/Succeeded from the votes. A subgraph state
stuck PENDING past voteEnd now resolves like a stale ACTIVE (tie/zero-for ->
DEFEATED, under quorum -> QUORUM_NOT_REACHED, else SUCCEEDED), mirroring the
yield-side getYieldDtfProposalState semantics. Optimistic paths and the
exact-boundary (<=) behavior are unchanged; the shared outcome logic is
extracted as getStandardFinalState next to getOptimisticFinalState.
The release changes behavior and types 0.4.x consumers depend on:
YieldDtfProposalState gained QUORUM_NOT_REACHED, rebalance detail auctions
went optional->required, and getIndexDtfPlatformFee throws where it returned
0%. Those (plus the exposure typing and 5m interval additions) get minor
changesets; the stale-PENDING outcome derivation stays a patch note.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/sdk/src/index-dtf/governance/utils.ts (1)

128-138: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify control flow to match the ACTIVE branch.

You can consolidate the timestamp > proposal.voteEnd checks to match the structure of the ACTIVE branch. This makes the logic easier to follow and ensures consistent grouping of optimistic and standard finalization.

♻️ Proposed refactor
-    } else if (timestamp > proposal.voteEnd && isOptimistic) {
-      state.state = getOptimisticFinalState(proposal, optimisticVetoThresholdVotes);
-    } else if (timestamp <= proposal.voteEnd) {
-      state.state = "ACTIVE";
-      state.deadline = proposal.voteEnd - timestamp;
-    } else {
-      // WHY: past the deadline FolioGovernor.state() derives Defeated/Succeeded
-      // from the vote counts even if the ACTIVE transition was never indexed —
-      // a stale PENDING is never EXPIRED (that is a queue-lifecycle state).
-      state.state = getStandardFinalState(proposal);
-    }
+    } else if (timestamp > proposal.voteEnd) {
+      // WHY: past the deadline FolioGovernor.state() derives Defeated/Succeeded
+      // from the vote counts even if the ACTIVE transition was never indexed —
+      // a stale PENDING is never EXPIRED (that is a queue-lifecycle state).
+      state.state = isOptimistic
+        ? getOptimisticFinalState(proposal, optimisticVetoThresholdVotes)
+        : getStandardFinalState(proposal);
+    } else {
+      state.state = "ACTIVE";
+      state.deadline = proposal.voteEnd - timestamp;
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/src/index-dtf/governance/utils.ts` around lines 128 - 138,
Refactor the branching around timestamp and proposal.voteEnd so the timestamp >
proposal.voteEnd cases are grouped together, with optimistic finalization via
getOptimisticFinalState when isOptimistic and standard finalization via
getStandardFinalState otherwise. Preserve the existing ACTIVE state and deadline
assignment for timestamps at or before proposal.voteEnd.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/sdk/src/index-dtf/governance/utils.ts`:
- Around line 128-138: Refactor the branching around timestamp and
proposal.voteEnd so the timestamp > proposal.voteEnd cases are grouped together,
with optimistic finalization via getOptimisticFinalState when isOptimistic and
standard finalization via getStandardFinalState otherwise. Preserve the existing
ACTIVE state and deadline assignment for timestamps at or before
proposal.voteEnd.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e25243f-0803-4357-99d3-1a03542685d8

📥 Commits

Reviewing files that changed from the base of the PR and between 7480fb2 and c51c120.

📒 Files selected for processing (8)
  • .changeset/exposure-api-types.md
  • .changeset/platform-fee-invalid-response.md
  • .changeset/price-history-5m-interval.md
  • .changeset/rebalance-detail-contract.md
  • .changeset/stale-pending-outcomes.md
  • .changeset/strict-tie-semantics.md
  • packages/sdk/src/index-dtf/governance/utils.test.ts
  • packages/sdk/src/index-dtf/governance/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/strict-tie-semantics.md

IndexDtfBrand is now the exact shape consumers store: nested dtf block,
creator/curator/socials always present, absent API values coerced to ''
defaults, basketType narrowed to percentage-based | unit-based. Removes
the need for app-side brand mapping layers.
getIndexDtfStatus({ address, chainId }) reads dtf-catalog directly with
case-insensitive address matching; absent entries are active. getFull and
ref.getStatus share the same lookup. useIndexDtfStatus becomes a trivial
sync wrapper; the async /discover scan, indexDtfStatusQueryOptions and the
status query key are gone.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/sdk/src/index-dtf/dtf/mappers.ts (1)

187-201: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor inconsistency: basketType isn't normalized like the other fields.

Every other string field routes through nonEmpty() (trims whitespace, treats blank as absent) before defaulting. basketType instead does a raw strict-equality check, so a value like " unit-based" or "Unit-Based" would silently fall back to "percentage-based" instead of erroring or matching. Low risk today, but worth aligning for consistency.

♻️ Optional normalization
-      basketType: dtf?.basketType === "unit-based" ? "unit-based" : "percentage-based",
+      basketType: nonEmpty(dtf?.basketType)?.trim().toLowerCase() === "unit-based" ? "unit-based" : "percentage-based",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/src/index-dtf/dtf/mappers.ts` around lines 187 - 201, The dtf
mapping’s basketType handling in the visible dtf mapper does not normalize input
consistently with the other fields. Update basketType to pass through the
existing nonEmpty normalization before determining the supported value,
preserving unit-based for normalized unit-based input and the existing
percentage-based fallback otherwise.
packages/react-sdk/src/index-dtf/use-index-dtf-performance.test.tsx (1)

42-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test case for zero values.

To prevent regressions, it is recommended to add a test case verifying that the live point is appended correctly when currentPrice and currentTotalSupply are explicitly 0.

🧪 Proposed test addition
     const composed = composeIndexDtfPerformance(points, 2, 100);
     expect(composed).toHaveLength(2);
     expect(composed[1]).toMatchObject({ price: 2, marketCap: 200, totalSupply: 100 });
+
+    const composedZero = composeIndexDtfPerformance(points, 0, 0);
+    expect(composedZero).toHaveLength(2);
+    expect(composedZero[1]).toMatchObject({ price: 0, marketCap: 0, totalSupply: 0 });
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-sdk/src/index-dtf/use-index-dtf-performance.test.tsx` around
lines 42 - 45, Add a test case in the composeIndexDtfPerformance tests that
calls the function with currentPrice and currentTotalSupply explicitly set to 0,
then verifies the live point is appended and retains those zero values. Keep the
existing positive-value assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/react-sdk/src/index-dtf/use-index-dtf-performance.ts`:
- Line 50: Update the live-point condition in the index DTF performance hook to
accept zero-valued currentPrice and currentTotalSupply by checking each
explicitly against undefined. Preserve the existing last-point timestamp guard
and append behavior.

In `@packages/react-sdk/src/index.ts`:
- Around line 213-227: Format and sort the newly added exports in the package
entrypoint according to the repository’s oxfmt configuration, including the
composeIndexDtfPerformance, dedupeIndexDtfPricePoints, useIndexDtfPerformance,
and useAccountBalancePnl exports and their associated type exports. Preserve the
exported symbols and module paths while ensuring the file passes the formatter
check.

---

Nitpick comments:
In `@packages/react-sdk/src/index-dtf/use-index-dtf-performance.test.tsx`:
- Around line 42-45: Add a test case in the composeIndexDtfPerformance tests
that calls the function with currentPrice and currentTotalSupply explicitly set
to 0, then verifies the live point is appended and retains those zero values.
Keep the existing positive-value assertions unchanged.

In `@packages/sdk/src/index-dtf/dtf/mappers.ts`:
- Around line 187-201: The dtf mapping’s basketType handling in the visible dtf
mapper does not normalize input consistently with the other fields. Update
basketType to pass through the existing nonEmpty normalization before
determining the supported value, preserving unit-based for normalized unit-based
input and the existing percentage-based fallback otherwise.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4caf969a-afdb-495e-bf73-3b60055424d8

📥 Commits

Reviewing files that changed from the base of the PR and between c51c120 and e44ec05.

📒 Files selected for processing (27)
  • .changeset/account-balance-pnl.md
  • .changeset/brand-display-shape.md
  • .changeset/index-dtf-performance-hook.md
  • .changeset/status-sync-catalog.md
  • packages/react-sdk/src/index-dtf-extra-hooks.ts
  • packages/react-sdk/src/index-dtf-query-options.ts
  • packages/react-sdk/src/index-dtf/use-account-balance-pnl.test.tsx
  • packages/react-sdk/src/index-dtf/use-account-balance-pnl.ts
  • packages/react-sdk/src/index-dtf/use-index-dtf-performance.test.tsx
  • packages/react-sdk/src/index-dtf/use-index-dtf-performance.ts
  • packages/react-sdk/src/index.ts
  • packages/react-sdk/src/query-keys.ts
  • packages/react-sdk/src/use-index-dtf-status.test.tsx
  • packages/sdk/src/index-dtf/dtf/account-pnl.test.ts
  • packages/sdk/src/index-dtf/dtf/account-pnl.ts
  • packages/sdk/src/index-dtf/dtf/discovery.test.ts
  • packages/sdk/src/index-dtf/dtf/discovery.ts
  • packages/sdk/src/index-dtf/dtf/index.test.ts
  • packages/sdk/src/index-dtf/dtf/index.ts
  • packages/sdk/src/index-dtf/dtf/mappers.ts
  • packages/sdk/src/index-dtf/dtf/status.test.ts
  • packages/sdk/src/index-dtf/dtf/status.ts
  • packages/sdk/src/index-dtf/index.ts
  • packages/sdk/src/index-dtf/namespace.ts
  • packages/sdk/src/index-dtf/ref.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/types/index-dtf.ts
💤 Files with no reviewable changes (3)
  • packages/sdk/src/index-dtf/dtf/discovery.ts
  • packages/react-sdk/src/index-dtf-query-options.ts
  • packages/sdk/src/index-dtf/dtf/discovery.test.ts

Comment thread packages/react-sdk/src/index-dtf/use-index-dtf-performance.ts Outdated
Comment thread packages/react-sdk/src/index.ts Outdated
…s out of the SDK

sdk keeps transport + data-hygiene primitives (snapshot read, selectPriceAtMark);
react-sdk is strictly the hook-per-read access layer, gaining
useIndexDtfAccountBalanceSnapshot and usePrefetchIndexDtfPriceHistory (so apps
never touch the sdk client directly). useAccountBalancePnl and
calculateAccountBalancePnl are deleted — a product metric like week-ago PnL is
app-side composition; its semantics change on design revisions, not protocol
versions, so it doesn't belong here.
- Live performance point accepts zero price/supply (defined-ness gate, not
  truthiness) with zero-vector regressions; prefetch covered by test.
- selectPriceAtMark is timestamp-aware with an optional mark (defaults to the
  old latest-positive behavior); snapshot read wired through namespace, ref,
  query options and hook, with a hook test.
- getIndexDtfStatus validates/normalizes the address before the catalog lookup.
- Brand normalization + governance control-flow cleanup; fresh GraphQL output.
- LICENSE shipped in all package tarballs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/wiki/log.md (1)

22-25: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the block-fetch wording.

packages/sdk/src/yield-dtf/governance.ts fetches a block whenever any PENDING or ACTIVE proposal exists, including Anastasius proposals that use block.timestamp; it is not limited to non-terminal Alexios proposals.

Suggested wording
-- fetching the block number only when a non-terminal Alexios proposal needs it.
+- fetching one latest block when a non-terminal proposal needs a chain timepoint (timestamp for Anastasius or block number for Alexios).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/wiki/log.md` around lines 22 - 25, Update the 2026-07-14
governance-hardening bullet in docs/wiki/log.md so its description of
getYieldDtfProposalState accurately states that block data is fetched whenever a
PENDING or ACTIVE proposal exists, including Anastasius proposals using
block.timestamp, rather than limiting this behavior to non-terminal Alexios
proposals.
🧹 Nitpick comments (2)
packages/react-sdk/src/hooks.ts (1)

125-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pass staleTime directly.

Line 138 adds conditional-spread noise; use { staleTime } unless this package’s exact optional-property configuration rejects undefined.

Proposed fix
       queryClient.prefetchQuery({
         ...indexDtfPriceHistoryQueryOptions(sdk, params),
-        ...(staleTime !== undefined ? { staleTime } : {}),
+        staleTime,
       }),

As per coding guidelines, use { value } rather than ...(value === undefined ? {} : { value }) unless omission is needed for exact optional typing or serialization behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-sdk/src/hooks.ts` around lines 125 - 142, Update
usePrefetchIndexDtfPriceHistory to pass staleTime directly in the prefetchQuery
options object, replacing the conditional spread with the concise { staleTime }
form unless the package’s exact optional-property typing requires omission of
undefined.

Source: Coding guidelines

.github/workflows/ci.yml (1)

47-48: 🩺 Stability & Availability | 🔵 Trivial

Bound the live-schema codegen check.

This step invokes GraphQL Codegen against remote schemas, and pnpm release:ci now runs the same check during publication. The wrapper has no process timeout, so a schema-provider stall can hold CI or release jobs until the runner timeout; add a bounded timeout or explicit job-level timeout.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 47 - 48, Bound the GraphQL Codegen
Check step so remote schema stalls cannot hang CI or release jobs indefinitely.
Add an explicit timeout to the step or its enclosing job, preserving the
existing pnpm graphql:codegen:check command and ensuring the timeout applies to
this live-schema validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/docs/src/pages/react-sdk/index-dtf-hooks.mdx`:
- Line 73: Update the `select` documentation in the React SDK hooks page so it
applies only to ordinary query-backed hooks, explicitly excluding
`useIndexDtfStatus` and `useIndexDtfPerformance`; preserve the existing guidance
to use `usePrefetchIndexDtfPriceHistory` for canonical price-history keys.

In `@docs/wiki/domains/sdk.md`:
- Line 29: Update the documentation sentence to hyphenate the compound modifier,
changing “GraphQL generated output” to “GraphQL-generated output” while
preserving the rest of the statement.
- Around line 26-31: Clarify the proposal-state bullet to explicitly scope its
vote, quorum, deadline, and subgraph-lag behavior to Index DTFs, or revise the
adjacent proposal-ID and Yield detail bullets so their Index-versus-Yield
distinctions are unambiguous. Preserve the stated Yield proposal-list and
detail-state behavior.

---

Outside diff comments:
In `@docs/wiki/log.md`:
- Around line 22-25: Update the 2026-07-14 governance-hardening bullet in
docs/wiki/log.md so its description of getYieldDtfProposalState accurately
states that block data is fetched whenever a PENDING or ACTIVE proposal exists,
including Anastasius proposals using block.timestamp, rather than limiting this
behavior to non-terminal Alexios proposals.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 47-48: Bound the GraphQL Codegen Check step so remote schema
stalls cannot hang CI or release jobs indefinitely. Add an explicit timeout to
the step or its enclosing job, preserving the existing pnpm
graphql:codegen:check command and ensuring the timeout applies to this
live-schema validation.

In `@packages/react-sdk/src/hooks.ts`:
- Around line 125-142: Update usePrefetchIndexDtfPriceHistory to pass staleTime
directly in the prefetchQuery options object, replacing the conditional spread
with the concise { staleTime } form unless the package’s exact optional-property
typing requires omission of undefined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bf90b63-2109-477a-a50f-d9d8b838eb90

📥 Commits

Reviewing files that changed from the base of the PR and between e44ec05 and 3b0fbfb.

⛔ Files ignored due to path filters (1)
  • packages/sdk/src/index-dtf/subgraph/dtf.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (51)
  • .changeset/account-balance-pnl.md
  • .changeset/status-sync-catalog.md
  • .github/workflows/ci.yml
  • .github/workflows/publish.yml
  • LICENSE
  • README.md
  • apps/docs/src/pages/protocol/data-sources.mdx
  • apps/docs/src/pages/react-sdk/index-dtf-hooks.mdx
  • apps/docs/src/pages/sdk/index-dtf.mdx
  • docs/index-dtf/discovery-holders.md
  • docs/index-dtf/issuance-redemption.md
  • docs/plans/register-index-dtf-react-sdk-migration.md
  • docs/protocol/data-sources.md
  • docs/register/interface.md
  • docs/wiki/decisions.md
  • docs/wiki/domains/react-sdk.md
  • docs/wiki/domains/sdk.md
  • docs/wiki/log.md
  • docs/wiki/progress.md
  • docs/wiki/project.md
  • package.json
  • packages/dtf-catalog/LICENSE
  • packages/react-sdk/LICENSE
  • packages/react-sdk/README.md
  • packages/react-sdk/src/hooks.ts
  • packages/react-sdk/src/index-dtf-extra-hooks.ts
  • packages/react-sdk/src/index-dtf-query-options.ts
  • packages/react-sdk/src/index-dtf/use-index-dtf-performance.test.tsx
  • packages/react-sdk/src/index-dtf/use-index-dtf-performance.ts
  • packages/react-sdk/src/index.ts
  • packages/react-sdk/src/query-options.test.ts
  • packages/react-sdk/src/use-index-dtf-account-balance-snapshot.test.tsx
  • packages/sdk/LICENSE
  • packages/sdk/src/index-dtf/dtf/account-pnl.test.ts
  • packages/sdk/src/index-dtf/dtf/account-pnl.ts
  • packages/sdk/src/index-dtf/dtf/discovery.test.ts
  • packages/sdk/src/index-dtf/dtf/exposure.test.ts
  • packages/sdk/src/index-dtf/dtf/index.test.ts
  • packages/sdk/src/index-dtf/dtf/mappers.ts
  • packages/sdk/src/index-dtf/dtf/platform-fee.test.ts
  • packages/sdk/src/index-dtf/dtf/price-history.test.ts
  • packages/sdk/src/index-dtf/dtf/status.test.ts
  • packages/sdk/src/index-dtf/dtf/status.ts
  • packages/sdk/src/index-dtf/governance/utils.ts
  • packages/sdk/src/index-dtf/index.ts
  • packages/sdk/src/index-dtf/namespace.test.ts
  • packages/sdk/src/index-dtf/namespace.ts
  • packages/sdk/src/index-dtf/rebalance/index.test.ts
  • packages/sdk/src/index-dtf/ref.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/yield-dtf/governance.ts
💤 Files with no reviewable changes (2)
  • packages/sdk/src/index-dtf/dtf/price-history.test.ts
  • packages/sdk/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/sdk/src/index-dtf/dtf/exposure.test.ts
  • packages/sdk/src/index-dtf/dtf/platform-fee.test.ts
  • packages/sdk/src/index-dtf/ref.ts
  • packages/sdk/src/index-dtf/rebalance/index.test.ts
  • .changeset/status-sync-catalog.md
  • packages/sdk/src/index-dtf/dtf/index.test.ts
  • packages/react-sdk/src/index-dtf/use-index-dtf-performance.ts
  • packages/sdk/src/index-dtf/dtf/status.ts
  • packages/react-sdk/src/index-dtf-query-options.ts
  • docs/wiki/progress.md
  • packages/sdk/src/index-dtf/namespace.ts
  • packages/sdk/src/index-dtf/index.ts
  • packages/sdk/src/index-dtf/dtf/discovery.test.ts
  • packages/sdk/src/index-dtf/dtf/status.test.ts
  • packages/sdk/src/index-dtf/dtf/mappers.ts

Comment thread apps/docs/src/pages/react-sdk/index-dtf-hooks.mdx
Comment thread docs/wiki/domains/sdk.md Outdated
Comment thread docs/wiki/domains/sdk.md Outdated
@lcamargof
lcamargof merged commit 6b02598 into main Jul 23, 2026
3 checks passed
@lcamargof
lcamargof deleted the sdk/hardening branch July 23, 2026 16:47
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.

1 participant