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.