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:
| Data | Why | Solution |
|---|
| Interest earned (lender) | ERC4626 doesn’t track per-user principal | Track deposits/withdrawals in your app |
| Historical APY | Pool rates change over time | Use an indexer or snapshot service |
| Transaction history | Not stored on-chain in queryable form | Index Deposit/Borrow/Repay events |
Use @varla/sdk/events for event decoding if you’re building an indexer.