From 3c80a0edcbe4b4a5fa24972d8663a3c5fdd85071 Mon Sep 17 00:00:00 2001 From: AbuJulaybeeb Date: Mon, 27 Apr 2026 23:51:35 +0100 Subject: [PATCH] feat: implement pool states (active, on-ice, frozen) --- .../borrowing/components/ui/BorrowTable.tsx | 46 ++++++++--- .../src/features/borrowing/hooks/useBorrow.ts | 1 + .../borrowing/hooks/useBorrowPools.ts | 13 +++- .../src/features/borrowing/types/borrowing.ts | 4 + .../features/borrowing/utils/borrowUtils.ts | 1 + .../lending/components/ui/LendTable.tsx | 76 ++++++++++++------- .../src/features/lending/hooks/useLend.ts | 2 + .../features/lending/hooks/useLendingPools.ts | 16 +++- .../src/features/lending/types/lending.ts | 3 + .../pools/components/PoolActionModal.tsx | 11 +++ .../pools/components/pages/PoolDetail.tsx | 57 ++++++++++---- .../features/pools/components/ui/PoolCard.tsx | 23 ++++-- .../src/features/pools/hooks/usePoolsData.ts | 1 + .../web-app/src/features/pools/types/pools.ts | 3 + .../adapters/NekoLendingAdapter.ts | 8 +- 15 files changed, 200 insertions(+), 65 deletions(-) diff --git a/apps/web-app/src/features/borrowing/components/ui/BorrowTable.tsx b/apps/web-app/src/features/borrowing/components/ui/BorrowTable.tsx index 8080810..665b1a7 100644 --- a/apps/web-app/src/features/borrowing/components/ui/BorrowTable.tsx +++ b/apps/web-app/src/features/borrowing/components/ui/BorrowTable.tsx @@ -102,12 +102,22 @@ export function BorrowTable({ {asset.liquidity} - +
+ + {asset.state !== "active" && ( + + {asset.state === 'on_ice' ? 'On Ice' : asset.state} + + )} +
)) @@ -173,12 +183,24 @@ export function BorrowTable({ /> - +
+ + {asset.state !== "active" && ( +
+ + Pool is {asset.state === 'on_ice' ? 'On Ice' : asset.state} + +
+ )} +
))} diff --git a/apps/web-app/src/features/borrowing/hooks/useBorrow.ts b/apps/web-app/src/features/borrowing/hooks/useBorrow.ts index b73c4a0..804f539 100644 --- a/apps/web-app/src/features/borrowing/hooks/useBorrow.ts +++ b/apps/web-app/src/features/borrowing/hooks/useBorrow.ts @@ -72,6 +72,7 @@ export function useBorrow() { collateralFactorDisplay: "Aggregated", liquidity, isActive: p.state === "active", + state: p.state, assetCode: token?.code ?? "?", collateralTokenCode: "", collateralFactor: 0, diff --git a/apps/web-app/src/features/borrowing/hooks/useBorrowPools.ts b/apps/web-app/src/features/borrowing/hooks/useBorrowPools.ts index 1afd188..f5ba819 100644 --- a/apps/web-app/src/features/borrowing/hooks/useBorrowPools.ts +++ b/apps/web-app/src/features/borrowing/hooks/useBorrowPools.ts @@ -39,7 +39,15 @@ async function fetchPoolPools( return []; } - if (poolState?.tag !== "Active") return []; + const stateTag = (poolState?.tag as string) || "Active"; + const state: import("@/lib/orchestrator/types/pool.types").PoolState = + stateTag === "Active" + ? "active" + : stateTag === "OnIce" + ? "on_ice" + : stateTag === "Frozen" + ? "frozen" + : "unknown"; const pools: BorrowPool[] = []; @@ -107,7 +115,8 @@ async function fetchPoolPools( interestRate, poolBalance, poolBalanceUSD: "Calculating...", - isActive: true, + isActive: state === "active", + state, contractId, }); } catch { diff --git a/apps/web-app/src/features/borrowing/types/borrowing.ts b/apps/web-app/src/features/borrowing/types/borrowing.ts index 4612bf6..f7b7687 100644 --- a/apps/web-app/src/features/borrowing/types/borrowing.ts +++ b/apps/web-app/src/features/borrowing/types/borrowing.ts @@ -1,3 +1,5 @@ +import type { PoolState } from "@/lib/orchestrator/types/pool.types"; + export interface BorrowPool { asset: string; assetCode: string; @@ -8,6 +10,7 @@ export interface BorrowPool { poolBalance: string; poolBalanceUSD: string; isActive: boolean; + state: PoolState; contractId: string; } @@ -22,6 +25,7 @@ export interface BorrowTableAsset { collateralFactorDisplay: string; liquidity: string; isActive: boolean; + state: PoolState; assetCode: string; collateralTokenCode: string; collateralFactor: number; diff --git a/apps/web-app/src/features/borrowing/utils/borrowUtils.ts b/apps/web-app/src/features/borrowing/utils/borrowUtils.ts index 840817e..1a1be9c 100644 --- a/apps/web-app/src/features/borrowing/utils/borrowUtils.ts +++ b/apps/web-app/src/features/borrowing/utils/borrowUtils.ts @@ -25,6 +25,7 @@ export function poolsToTableAssets(pools: BorrowPool[]): BorrowTableAsset[] { collateralFactorDisplay: `${pool.collateralFactor}%`, liquidity, isActive: pool.isActive, + state: pool.state, assetCode: pool.assetCode, collateralTokenCode: pool.collateralTokenCode, collateralFactor: pool.collateralFactor, diff --git a/apps/web-app/src/features/lending/components/ui/LendTable.tsx b/apps/web-app/src/features/lending/components/ui/LendTable.tsx index f9f1c9b..3ff9098 100644 --- a/apps/web-app/src/features/lending/components/ui/LendTable.tsx +++ b/apps/web-app/src/features/lending/components/ui/LendTable.tsx @@ -87,19 +87,30 @@ export function LendTable({ {!hideActions && ( -
- - +
+
+ + +
+ {pool.state !== "active" && ( + + {pool.state === 'on_ice' ? 'On Ice' : pool.state} + + )}
)} @@ -154,19 +165,32 @@ export function LendTable({
{!hideActions && ( -
- - +
+
+ + +
+ {pool.state !== "active" && ( +
+ + Pool is {pool.state === 'on_ice' ? 'On Ice' : pool.state} + +
+ )}
)} diff --git a/apps/web-app/src/features/lending/hooks/useLend.ts b/apps/web-app/src/features/lending/hooks/useLend.ts index 394f8b1..38b64c2 100644 --- a/apps/web-app/src/features/lending/hooks/useLend.ts +++ b/apps/web-app/src/features/lending/hooks/useLend.ts @@ -95,6 +95,7 @@ export function useLend() { feeApy: `${pool.interestRate.toFixed(2)}%`, liquidity, isActive: pool.isActive, + state: pool.state, assetCode: pool.assetCode, asset: pool.asset, bTokenRate: pool.bTokenRate, @@ -124,6 +125,7 @@ export function useLend() { feeApy: p.apy > 0 ? `${p.apy.toFixed(2)}%` : "0.00%", liquidity, isActive: p.state === "active", + state: p.state, assetCode: token?.code ?? "?", asset: token?.address ?? "", bTokenRate: undefined, diff --git a/apps/web-app/src/features/lending/hooks/useLendingPools.ts b/apps/web-app/src/features/lending/hooks/useLendingPools.ts index 05a2080..f8989e5 100644 --- a/apps/web-app/src/features/lending/hooks/useLendingPools.ts +++ b/apps/web-app/src/features/lending/hooks/useLendingPools.ts @@ -10,6 +10,8 @@ import { fromSmallestUnit } from "@/lib/helpers/tokenUtils"; import { getAvailableTokens } from "@/lib/helpers/stellar/soroswap"; import { parseInterestRateFromContractResult } from "@/lib/helpers/lendingUtils"; +import type { PoolState } from "@/lib/orchestrator/types/pool.types"; + export interface LendingPool { asset: string; assetCode: string; @@ -18,6 +20,7 @@ export interface LendingPool { interestRate: number; bTokenRate: string; isActive: boolean; + state: PoolState; contractId: string; } @@ -46,7 +49,15 @@ async function fetchLendingPools( return []; } - if (poolState?.tag !== "Active") return []; + const stateTag = (poolState?.tag as string) || "Active"; + const state: PoolState = + stateTag === "Active" + ? "active" + : stateTag === "OnIce" + ? "on_ice" + : stateTag === "Frozen" + ? "frozen" + : "unknown"; const pools: LendingPool[] = []; @@ -109,7 +120,8 @@ async function fetchLendingPools( poolBalanceUSD: "Calculating...", interestRate, bTokenRate, - isActive: true, + isActive: state === "active", + state, contractId, }); } catch { diff --git a/apps/web-app/src/features/lending/types/lending.ts b/apps/web-app/src/features/lending/types/lending.ts index 6beedc2..1f1a9df 100644 --- a/apps/web-app/src/features/lending/types/lending.ts +++ b/apps/web-app/src/features/lending/types/lending.ts @@ -1,3 +1,5 @@ +import type { PoolState } from "@/lib/orchestrator/types/pool.types"; + export interface PoolData { id: string; name: string; @@ -8,6 +10,7 @@ export interface PoolData { feeApy: string; liquidity: string; isActive: boolean; + state: PoolState; assetCode: string; asset: string; bTokenRate?: string; diff --git a/apps/web-app/src/features/pools/components/PoolActionModal.tsx b/apps/web-app/src/features/pools/components/PoolActionModal.tsx index aabf6c9..59fdb22 100644 --- a/apps/web-app/src/features/pools/components/PoolActionModal.tsx +++ b/apps/web-app/src/features/pools/components/PoolActionModal.tsx @@ -70,6 +70,17 @@ export function PoolActionModal({ e.preventDefault(); if (!address) return; + // Safety check for pool state + if (pool.state === "frozen") return; + if ( + pool.state === "on_ice" && + !["withdraw", "repay", "withdrawCollateral", "claimRewards"].includes( + action + ) + ) { + return; + } + const onSuccess = async () => { setAmount(""); await Promise.all([ diff --git a/apps/web-app/src/features/pools/components/pages/PoolDetail.tsx b/apps/web-app/src/features/pools/components/pages/PoolDetail.tsx index 134841b..814d5b1 100644 --- a/apps/web-app/src/features/pools/components/pages/PoolDetail.tsx +++ b/apps/web-app/src/features/pools/components/pages/PoolDetail.tsx @@ -139,11 +139,26 @@ const PoolDetail: React.FC = ({ params }) => { {typeLabel}
-
+
+ {pool.state === "active" && ( +
+
+ Active +
+ )} + {pool.state === "on_ice" && ( +
+
+ On Ice +
+ )} + {pool.state === "frozen" && ( +
+
+ Frozen +
+ )} +
@@ -159,8 +174,12 @@ const PoolDetail: React.FC = ({ params }) => {

Status

-

- {pool.state} +

+ {pool.state === 'on_ice' ? 'On Ice' : pool.state}

@@ -221,8 +240,9 @@ const PoolDetail: React.FC = ({ params }) => {
{(pool.type === "blend" || pool.type === "neko") && ( @@ -231,56 +251,63 @@ const PoolDetail: React.FC = ({ params }) => { pool.type !== "blend" && pool.type !== "neko" && ( )} {supportedActions.includes("withdraw") && ( )} {supportedActions.includes("borrow") && ( )} {supportedActions.includes("repay") && ( )} {supportedActions.includes("supplyCollateral") && ( )} {supportedActions.includes("withdrawCollateral") && ( )} {supportedActions.includes("claimRewards") && ( diff --git a/apps/web-app/src/features/pools/components/ui/PoolCard.tsx b/apps/web-app/src/features/pools/components/ui/PoolCard.tsx index 5cb7236..c79e6d3 100644 --- a/apps/web-app/src/features/pools/components/ui/PoolCard.tsx +++ b/apps/web-app/src/features/pools/components/ui/PoolCard.tsx @@ -87,11 +87,24 @@ export const PoolCard: React.FC = ({ {}
-
+ {pool.state === "active" && ( +
+
+ Active +
+ )} + {pool.state === "on_ice" && ( +
+
+ On Ice +
+ )} + {pool.state === "frozen" && ( +
+
+ Frozen +
+ )}
diff --git a/apps/web-app/src/features/pools/hooks/usePoolsData.ts b/apps/web-app/src/features/pools/hooks/usePoolsData.ts index ab6de81..0d470c1 100644 --- a/apps/web-app/src/features/pools/hooks/usePoolsData.ts +++ b/apps/web-app/src/features/pools/hooks/usePoolsData.ts @@ -71,6 +71,7 @@ export function usePoolsData() { feeApy: apy, liquidity, isActive: pool.state === "active", + state: pool.state, type: pool.type, }; }); diff --git a/apps/web-app/src/features/pools/types/pools.ts b/apps/web-app/src/features/pools/types/pools.ts index 941c20d..a42fe99 100644 --- a/apps/web-app/src/features/pools/types/pools.ts +++ b/apps/web-app/src/features/pools/types/pools.ts @@ -1,3 +1,5 @@ +import type { PoolState } from "@/lib/orchestrator/types/pool.types"; + export interface PoolCardData { id: string; token1: string; @@ -7,6 +9,7 @@ export interface PoolCardData { feeApy: string; liquidity: string; isActive: boolean; + state: PoolState; type: string; } diff --git a/apps/web-app/src/lib/orchestrator/adapters/NekoLendingAdapter.ts b/apps/web-app/src/lib/orchestrator/adapters/NekoLendingAdapter.ts index 8a0be4f..02845ad 100644 --- a/apps/web-app/src/lib/orchestrator/adapters/NekoLendingAdapter.ts +++ b/apps/web-app/src/lib/orchestrator/adapters/NekoLendingAdapter.ts @@ -141,9 +141,11 @@ export class NekoLendingAdapter implements BasePoolAdapter { state: stateTag === "Active" ? "active" - : stateTag === "Frozen" - ? "frozen" - : "unknown", + : stateTag === "OnIce" + ? "on_ice" + : stateTag === "Frozen" + ? "frozen" + : "unknown", supportedActions: SUPPORTED_ACTIONS, metadata: { contractId,