Skip to content

[GF-12] [FRONTEND] Data Service Layer (Soroban RPC hooks, price feeds, TVL/APY) #44

@wumibals

Description

@wumibals

Overview

⚠️ Depends on: #41 (GF-08 — TypeScript SDK) and #56 (GF-11 — Deployment Scripts, for real contract addresses).

Build the data layer that connects the frontend to live on-chain data. This unblocks all interactive pages (deposit, portfolio, analytics, protocol management). Without it, every stat, APY, and TVL figure in the app remains a hardcoded placeholder.

Problem

Every number displayed in the app is currently hardcoded:

  • Landing page stats bar (app/src/app/page.tsx): "4", "1.40×", "0%", "35%" — static strings
  • Dashboard (app/src/app/dashboard/page.tsx): vault tier data is a hardcoded VAULT_TIERS array
  • No RPC hooks, no price feeds, no TVL aggregation, no APY calculation logic exists

Proposed Solution

1. RPC service (app/src/services/rpc.ts)
Initialise a SorobanRpc.Server instance using the NEXT_PUBLIC_SOROBAN_RPC_URL env var. Export a singleton used by all hooks.

2. Contract hooks (app/src/hooks/useVault.ts, usePosition.ts, useAllocations.ts)
Create React hooks backed by the TypeScript SDK (GF-08):

  • usePosition(address, tier) — reads a user's position from VaultRouter
  • useTotalShares(tier) — reads total shares per vault tier
  • useAllocations() — reads current AMM pool allocations from StrategyVault
  • useLastHarvest() — reads last harvest ledger from Harvester

3. Price feeds (app/src/services/prices.ts)
Fetch XLM, EURC, and AQUA prices using the Stellar DEX order book API (GET /order_book?selling_asset_type=native&buying_asset_code=USDC). Cache results for 60 seconds. Export useAssetPrices() hook.

4. TVL aggregation (app/src/hooks/useTVL.ts)
Calculate live TVL per vault and total:

  • Read total_shares per tier vault
  • For Flex: TVL = total shares (1.00× multiplier)
  • For L3/L6/L12: TVL = total shares / multiplier (reverse the share inflation)
  • Export useTVL() returning per-tier and aggregate values

5. APY calculation (app/src/hooks/useAPY.ts)
Calculate trailing 7-day and 30-day APY:

  • Query harvest history from the event indexer (or estimate from the last two harvest events)
  • Annualise: apy = (harvest_yield / tvl) * (365 / harvest_interval_days)
  • Export useAPY(tier)

6. Update landing page stats bar
Replace hardcoded values in app/src/app/page.tsx with live data from useTVL() and useAPY().

Acceptance Criteria

  • usePosition returns live on-chain position data for a connected wallet
  • useTVL returns live TVL per vault and aggregate total (not hardcoded)
  • useAPY returns 7-day trailing APY per vault
  • useAllocations returns current pool allocation percentages
  • Price feeds return XLM, EURC, AQUA prices in USD, cached for 60s
  • Landing page stats bar shows live data (TVL, APY, deposit count) instead of static strings
  • All hooks handle loading and error states gracefully (no unhandled promise rejections)
  • RPC calls use the NEXT_PUBLIC_SOROBAN_RPC_URL env var, not a hardcoded URL

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions