Skip to content

feat: use arbitrum staking duration unchained endpoint - #11098

Merged
0xApotheosis merged 1 commit into
developfrom
arbitrum-moralis-dev
Nov 16, 2025
Merged

feat: use arbitrum staking duration unchained endpoint#11098
0xApotheosis merged 1 commit into
developfrom
arbitrum-moralis-dev

Conversation

@kaladinlight

@kaladinlight kaladinlight commented Nov 14, 2025

Copy link
Copy Markdown
Member

Description

Leverage new /rfox/staking-duration endpoint exposed by unchained instead of calculating client side. This allows us to fully cut over arbitrum in web (without breaking rfox details). Note, the event log cache is updated every 15 minutes at this time. This means that for newly staked users or users that fully unstake, there will be some delay for the Time in Pool value to update.

Update production and private to point to dev endpoint until everything is fully deployed and we can cut back to prod endpoints.

Issue (if applicable)

N/A

Risk

High Risk PRs Require 2 approvals

Low

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Testing

  • Ensure time in pool is displayed correctly for rfox across accounts and staking assets

Engineering

☝️

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)

☝️

Screenshots (if applicable)

image

Summary by CodeRabbit

  • Chores

    • Updated Arbitrum API endpoints to point to development infrastructure.
  • Refactor

    • Refactored RFOX staking duration calculation to use an improved data-fetching approach.

@kaladinlight
kaladinlight requested a review from a team as a code owner November 14, 2025 18:34
@coderabbitai

coderabbitai Bot commented Nov 14, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Environment variables for Arbitrum endpoints were updated from production to development hosts. The RFOX staking query logic was refactored from client-side blockchain log processing to a provider-based HTTP API call approach, with related files removed.

Changes

Cohort / File(s) Summary
Arbitrum Endpoint Configuration
.env.private, .env.production
Updated VITE_UNCHAINED_ARBITRUM_HTTP_URL and VITE_UNCHAINED_ARBITRUM_WS_URL from production API endpoints to development endpoints (dev-api.arbitrum.shapeshift.com)
RFOX Client-Side Log Query Removal
src/pages/RFOX/hooks/useAccountLogsQuery.ts
Entire file removed; deleted exported functions getAccountLogsQueryKey() and getAccountLogsQueryFn() that fetched blockchain logs via Viem client
RFOX Time-In-Pool Query Test Removal
src/pages/RFOX/hooks/useTimeInPoolQuery.test.ts
Entire test file removed; deleted all unit tests for getTimeInPoolSeconds including mocks for viemClientByNetworkId and block timestamp logic
RFOX Time-In-Pool Query Refactor
src/pages/RFOX/hooks/useTimeInPoolQuery.ts
Migrated from client-side log-based staking duration computation to provider-based HTTP API approach; removed dayjs and viem dependencies; replaced getTimeInPoolSeconds with getRfoxStakingDuration provider call; updated hook to use EVM chain adapter and tightened getTimeInPoolQueryKey() parameter typing; removed UseTimeInPoolQueryProps export

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Hook as useTimeInPoolQuery
    participant Provider as HTTP Provider
    participant API as getRfoxStakingDuration<br/>(Backend API)
    
    rect rgb(200, 220, 255)
    note over User,API: NEW: Provider-Based Flow
    User->>Hook: Request time in pool
    Hook->>Provider: Get EVM chain adapter
    activate Provider
    Provider-->>Hook: Chain adapter (HTTP)
    deactivate Provider
    Hook->>API: Call getRfoxStakingDuration<br/>(staking account, contract)
    activate API
    API-->>Hook: Staking duration (ms)
    deactivate API
    Hook->>Hook: Convert to BigInt result
    Hook-->>User: Time in pool (BigInt)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Key areas requiring attention:
    • The migration logic in useTimeInPoolQuery.ts: verify the provider call chain (EVM chain adapter → HTTP provider → getRfoxStakingDuration) is correctly implemented and handles errors
    • Ensure the contract mapping and address formatting (fromAccountId, arbitrumChainId) produce correct parameters for the API call
    • Confirm type tightening in getTimeInPoolQueryKey() parameters doesn't break existing callers
    • Verify removal of client-side logic doesn't introduce regressions in staking duration calculations
    • The endpoint change from production to development—confirm this is intentional and scoped appropriately

Suggested reviewers

  • 0xApotheosis
  • gomesalexandre
  • NeOMakinG

Poem

🐰 From chain logs we hop away today,
Provider paths now light the way,
API calls replace the viem dance,
Staking durations at a glance,
Dev endpoints green, the future's set,
Refactoring magic—no regrets! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: migrating to use Arbitrum's staking duration unchained endpoint instead of client-side log processing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch arbitrum-moralis-dev

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 and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/pages/RFOX/hooks/useTimeInPoolQuery.ts (1)

54-64: Consider explicit error handling and documenting the 0 fallback.

The query function lacks explicit error handling and uses a silent fallback to 0 when the staking duration is not found.

Consider these improvements:

  1. Error handling: While React Query will catch thrown errors, consider adding explicit logging for debugging
  2. Document fallback: The ?? 0 fallback might hide cases where the contract is not found in the response

Apply this diff:

 return async () => {
   const stakingDuration = await provider.getRfoxStakingDuration({
     address: fromAccountId(stakingAssetAccountId).account,
   })
-
-  return BigInt(stakingDuration[getStakingContract(stakingAssetId)] ?? 0)
+  
+  const contract = getStakingContract(stakingAssetId)
+  const duration = stakingDuration[contract]
+  
+  // Note: Returns 0 for newly staked users until cache refreshes (up to 15 min)
+  if (duration === undefined) {
+    console.debug(`No staking duration found for contract ${contract}`)
+  }
+  
+  return BigInt(duration ?? 0)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b023a92 and fe36038.

📒 Files selected for processing (5)
  • .env.private (1 hunks)
  • .env.production (1 hunks)
  • src/pages/RFOX/hooks/useAccountLogsQuery.ts (0 hunks)
  • src/pages/RFOX/hooks/useTimeInPoolQuery.test.ts (0 hunks)
  • src/pages/RFOX/hooks/useTimeInPoolQuery.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • src/pages/RFOX/hooks/useTimeInPoolQuery.test.ts
  • src/pages/RFOX/hooks/useAccountLogsQuery.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/RFOX/hooks/useTimeInPoolQuery.ts (4)
packages/caip/src/assetId/assetId.ts (1)
  • AssetId (17-17)
src/lib/utils/evm/index.ts (1)
  • assertGetEvmChainAdapter (185-194)
packages/caip/src/constants.ts (1)
  • arbitrumChainId (66-66)
src/pages/RFOX/helpers.ts (1)
  • getStakingContract (50-54)
🪛 dotenv-linter (4.0.0)
.env.production

[warning] 24-24: [UnorderedKey] The VITE_UNCHAINED_ARBITRUM_HTTP_URL key should go before the VITE_UNCHAINED_AVALANCHE_HTTP_URL key

(UnorderedKey)


[warning] 25-25: [UnorderedKey] The VITE_UNCHAINED_ARBITRUM_WS_URL key should go before the VITE_UNCHAINED_AVALANCHE_HTTP_URL key

(UnorderedKey)

.env.private

[warning] 18-18: [UnorderedKey] The VITE_UNCHAINED_ARBITRUM_HTTP_URL key should go before the VITE_UNCHAINED_AVALANCHE_HTTP_URL key

(UnorderedKey)


[warning] 19-19: [UnorderedKey] The VITE_UNCHAINED_ARBITRUM_WS_URL key should go before the VITE_UNCHAINED_AVALANCHE_HTTP_URL key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install and Cache
🔇 Additional comments (8)
.env.private (1)

18-19: Verify consistency with production endpoint changes.

The dev endpoint configuration here is consistent with .env.production. Since this is a private environment, the risk is lower than production, but ensure these are also reverted when production endpoints are switched back.

src/pages/RFOX/hooks/useTimeInPoolQuery.ts (6)

1-9: LGTM! Imports align with provider-based refactor.

The new imports support the shift from client-side log processing to the unchained API approach.


19-33: LGTM! Improved type safety.

The function signature now requires explicit AccountId | undefined and AssetId | undefined types instead of loose string types, improving type safety.


35-39: LGTM! Type definition aligns with provider-based approach.

The updated type correctly reflects the new implementation requirements.


50-52: LGTM! Query key correctly memoized.

Dependencies correctly track the inputs to the query key.


66-66: LGTM! Clean React Query integration.

The hook correctly returns the query result with optional select transformation.


46-48: Verify stakingAssetId is always on Arbitrum.

The provider is hardcoded to arbitrumChainId without validating that stakingAssetId belongs to the Arbitrum chain. If stakingAssetId could be on a different chain, this will cause incorrect behavior.

Run this script to verify all staking assets are on Arbitrum:

If staking assets can be on other chains, apply this diff to add validation:

 const provider = useMemo(() => {
+  // Validate stakingAssetId is on Arbitrum
+  if (stakingAssetId && !stakingAssetId.startsWith('eip155:42161/')) {
+    throw new Error(`Staking asset ${stakingAssetId} must be on Arbitrum chain`)
+  }
   return assertGetEvmChainAdapter(arbitrumChainId).httpProvider as unchained.evm.arbitrum.V1Api
-}, [])
+}, [stakingAssetId])
.env.production (1)

24-25: Verify the actual intent: dev-api.arbitrum change appears intentional, not temporary.

The review comment claims the PR description states this is "temporary," but verification reveals this is a deliberate feature change, not a temporary deployment workaround:

  • Commit type: feat (feature, not fix or hotfix)
  • Significant code refactoring: 273 lines removed from useTimeInPoolQuery, 31 added
  • Both .env.production and .env.private updated identically
  • Commit message focuses on "use arbitrum staking duration unchained endpoint" with no mention of temporary status
  • No TODO or tracking comments present in either file

However, the concern about dev-api in production remains valid: VITE_ARBITRUM_NODE_URL still uses production (api.arbitrum.shapeshift.com), creating mixed environment endpoints.

Action needed: Confirm whether pointing VITE_UNCHAINED_ARBITRUM endpoints to dev-api is:

  1. An intentional architectural decision for the staking duration feature (appears likely based on code changes), or
  2. An accidental configuration that needs reverting to api.arbitrum.shapeshift.com

If intentional, document why dev-api is appropriate for production; if unintentional, revert both env files to use production endpoints.

@0xApotheosis 0xApotheosis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Time in pool still working correctly.

Image

@0xApotheosis
0xApotheosis merged commit 01df06a into develop Nov 16, 2025
4 checks passed
@0xApotheosis
0xApotheosis deleted the arbitrum-moralis-dev branch November 16, 2025 23:02
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.

2 participants