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
Overview
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:
app/src/app/page.tsx):"4","1.40×","0%","35%"— static stringsapp/src/app/dashboard/page.tsx): vault tier data is a hardcodedVAULT_TIERSarrayProposed Solution
1. RPC service (
app/src/services/rpc.ts)Initialise a
SorobanRpc.Serverinstance using theNEXT_PUBLIC_SOROBAN_RPC_URLenv 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 VaultRouteruseTotalShares(tier)— reads total shares per vault tieruseAllocations()— reads current AMM pool allocations from StrategyVaultuseLastHarvest()— reads last harvest ledger from Harvester3. 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. ExportuseAssetPrices()hook.4. TVL aggregation (
app/src/hooks/useTVL.ts)Calculate live TVL per vault and total:
total_sharesper tier vaultuseTVL()returning per-tier and aggregate values5. APY calculation (
app/src/hooks/useAPY.ts)Calculate trailing 7-day and 30-day APY:
apy = (harvest_yield / tvl) * (365 / harvest_interval_days)useAPY(tier)6. Update landing page stats bar
Replace hardcoded values in
app/src/app/page.tsxwith live data fromuseTVL()anduseAPY().Acceptance Criteria
usePositionreturns live on-chain position data for a connected walletuseTVLreturns live TVL per vault and aggregate total (not hardcoded)useAPYreturns 7-day trailing APY per vaultuseAllocationsreturns current pool allocation percentagesNEXT_PUBLIC_SOROBAN_RPC_URLenv var, not a hardcoded URL