Skip to main content

Reading protocol data

Two view contracts give you everything the Sward interface itself runs on. No indexer required.

All reserves in one call​

UiPoolDataProvider.getReservesData(provider) returns every reserve's full state: symbols, decimals, oracle prices, rates, indexes, caps, rate-model parameters, and configuration flags.

import { createPublicClient, http } from 'viem';

const client = createPublicClient({
transport: http('https://rpc.testnet.chain.robinhood.com'),
});

const [reserves, baseCurrency] = await client.readContract({
address: '0xb98713a9430A773564ED5EC1FAc87105EeCAC6bb',
abi: uiPoolDataProviderAbi,
functionName: 'getReservesData',
args: ['0x7697215A4CDdeb10785c4b33bE773E0F30a4b2c7'],
});

Rates come back as rays (27-decimal fixed point). Divide by 1e27 for the simple annual rate, then compound per second for the APY shown in the UI:

const apr = Number(reserve.variableBorrowRate) / 1e27;
const apy = (1 + apr / 31_536_000) ** 31_536_000 - 1;

One user's position​

Pool.getUserAccountData(user) returns the aggregate position: total collateral and debt in the base currency (USD, 8 decimals), available borrows, the weighted liquidation threshold and LTV, and the health factor (18 decimals, type(uint256).max when there is no debt).

Per-reserve balances come from UiPoolDataProvider.getUserReservesData(provider, user); multiply the scaled balances by the reserve's current index to get live amounts.

Wallet balances in bulk​

WalletBalanceProvider.batchBalanceOf([user], tokens) reads any number of ERC-20 balances in a single call, which is how the app fills the wallet column in Markets.