Skip to main content
These recipes map SDK helpers to typical frontend screens. Each shows exactly which views to call and what data you get back.

Borrow page (borrower dashboard)

import * as views from "@varla/sdk/views";

// Account overview
const account = await views.readAccountSnapshot({ client, core, user });
// → { portfolioValue, collateralValue, debt, healthFactor, maxBorrow, positionIds, balances }

// Repay timing (1-minute delay)
const timing = await views.readRepayTiming({ client, core, user });
// → { borrowedAt, canRepayAt, isRepayAllowed }

// Oracle guards (can liquidation proceed?)
const guards = await views.readOracleGuardsStatus({ client, core, user });
// → { ok, badPid, until }
If healthFactor is maxUint256, the user has no debt. Show “N/A” instead of a large number.

Lend page (lender dashboard)

import * as views from "@varla/sdk/views";

// User's position
const lender = await views.readLenderSnapshot({ client, pool, user });
// → { shares, assets, maxWithdrawAssets, maxRedeemShares }

// Pool rates
const rates = await views.readPoolRates({ client, pool });
// → { utilizationWad, borrowRateRay, supplyApyRay }

// Pool share price (optional, for "price per share" display)
const price = await views.readPoolSharePrice({ client, pool });
// → { assetsPerShareWad }
Don’t display assets as “withdrawable”. Use maxWithdrawAssets — it accounts for liquidity constraints.

Home page / pool overview

import * as views from "@varla/sdk/views";

// Pool snapshot (everything in one call)
const pool = await views.readPoolSnapshot({ client, pool: poolAddress });
// → { totalAssets, totalBorrowed, utilization, borrowRate, supplyApy, ... }

// Pool caps (capacity constraints)
const caps = await views.readPoolCaps({ client, pool: poolAddress });
// → { depositCap, borrowCap, depositCapRemaining, borrowCapRemaining }

// Pool health score (simple risk signal)
const health = await views.readPoolHealthScore({ client, pool: poolAddress });
// → { kind: "ok", utilizationWad, scoreBps } or { kind: "no-liquidity" }

Position details (oracle data)

import * as views from "@varla/sdk/views";

// Single position
const pos = await views.readPositionSnapshot({ client, oracle, positionId });
// → { priceOk, priceE8, manuallyInvalidated, riskTier, earlyClosureFactorWad, ... }

// Multiple positions (batched)
const positions = await views.readManyPositionSnapshots({ client, oracle, positionIds });

// Price + TWAP
const price = await views.readOraclePriceData({ client, oracle, positionId });
// → { price, twap, liquidity, lastUpdated, isValid }

Liquidation preview

import * as views from "@varla/sdk/views";

// Can this user be liquidated?
const canLiq = await views.readCanLiquidate({ client, core, user });
// → { canLiquidate, healthFactor }

// Liquidation bonus for a position at current HF
const bonus = await views.readLiquidationBonusBps({ client, core, positionId, healthFactor });
// → { bonusBps }

// Preview (what happens if you liquidate X debt)
const preview = await views.readPreviewLiquidation({ client, liquidator, user, positionId, debtToCover });
// → { collateralToSeize, bonusAmount, protocolFee, ... }

What the SDK doesn’t provide

Some data requires app-side tracking or an indexer:
DataWhySolution
Interest earned (lender)ERC4626 doesn’t track per-user principalTrack deposits/withdrawals in your app
Historical APYPool rates change over timeUse an indexer or snapshot service
Transaction historyNot stored on-chain in queryable formIndex Deposit/Borrow/Repay events
Use @varla/sdk/events for event decoding if you’re building an indexer.