Skip to main content

Market data

APR and estimated APY

client.market.listPools() and client.market.getPoolRate(...) return borrow and supply annual percentage rates (APRs) as 27-decimal fixed-point integers. Divide a rate by RATE_SCALE to get its decimal value.

Pools and pool-rate responses also include estimated annual percentage yields (APYs). Borrow APY mirrors the protocol's per-second compounding. Supply APY uses the scheduled 15-second pool synchronization interval. Both estimates assume that the rate in the response stays constant for a 365-day year.

Rates change with pool utilization, and protocol activity can synchronize a pool between scheduled timer ticks. Treat these values as estimates based on the rate at the time of the query, not as guaranteed or historical yield.

You can calculate the same values directly:

import { estimateBorrowApy, estimateSupplyApy } from "@liquidium/client";

const estimatedBorrowApy = estimateBorrowApy(pool.borrowingRate);
const estimatedSupplyApy = estimateSupplyApy(pool.lendingRate);

Price timestamps

If the UI shows when it last refreshed market prices, use client.market.getAssetPriceSnapshot():

const { prices, fetchedAt } = await client.market.getAssetPriceSnapshot();

fetchedAt is the Unix timestamp when the SDK received the canister response. It is not the oracle observation timestamp because the lending canister does not include that timestamp in its public price response.

Asset names

Every Pool includes a stable displayName. You can get the same metadata without fetching pools through getAssetMetadata(asset) or the exported ASSET_METADATA record:

import { getAssetMetadata } from "@liquidium/client";

const { displayName } = getAssetMetadata("BTC");

Use the canonical asset symbol for protocol logic. Display names are presentation metadata only. Applications provide their own icon assets, so the SDK does not introduce framework, network, or Content Security Policy requirements.

Health factor and risk scales

Health factors use three decimal places: 1000n means 1.0. When you format a finite value, use healthFactorDecimals or the exported HEALTH_FACTOR_SCALE. healthFactor is null when the profile has no debt because its health factor is unbounded.

Pool rate fields such as lendingRate, borrowingRate, and utilizationRate use the 27-decimal rateDecimals scale. Pool risk fields such as maxLtv, liquidationThreshold, liquidationBonus, protocolLiquidationFee, and reserveFactor use basis points instead.

Profile existence

Position queries return empty values for both registered profiles with no positions and unknown principal IDs. If your app must distinguish between them, call client.accounts.profileExists(...):

const isRegistered = await client.accounts.profileExists(profileId);

The lending canister does not provide a direct profile-existence query. The SDK uses the production invariant that every registered profile has at least one linked wallet and that the final wallet cannot be removed. This method cannot detect profiles inserted through development-only state seeding without wallets.