Query market state, interest rates, and utilisation for Jupiter Lend liquidity layer.
The Liquidity layer is the foundation of Jupiter Lend, holding all the underlying assets. While you usually interact with the Earn (Lending) and Borrow (Vaults) layers to perform operations, querying the Liquidity layer directly is useful for analytics, dashboards, and APY aggregators.The @jup-ag/lend-read SDK provides a Liquidity module to fetch real-time market data, interest rates, and raw user balances.
The Liquidity module is read-only. To supply or borrow assets, use the Earn or Borrow modules instead.
supplyExchangePrice & borrowExchangePrice: These convert the protocol’s raw internal accounting numbers into actual token amounts. As interest accrues, these prices increase. The SDK methods (like getUserSupplyData) automatically apply these exchange prices to give you human-readable token amounts.
Utilisation
lastStoredUtilization: The ratio of borrowed assets to supplied assets. High utilisation drives up both supply and borrow interest rates.
Limits
withdrawalLimit & borrowLimit: To protect against flash crashes or bank runs, Jupiter Lend implements automated expanding limits. You can query withdrawable and borrowable on user data objects to see exactly how much liquidity a user can move in the current block.
Use listedTokens() as your starting point to dynamically discover which markets exist on Jupiter Lend. This fetches an array of all supported token mints (PublicKey objects) that have initialised reserves in the Liquidity protocol, allowing your application to automatically support new tokens as they are added without hardcoding addresses.
Copy
Ask AI
import { Client } from "@jup-ag/lend-read";import { Connection } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com");const client = new Client(connection);// Fetch all supported token mintsconst supportedTokens = await client.liquidity.listedTokens();console.log(`Jupiter Lend supports ${supportedTokens.length} assets.`);
Because interest accrues constantly, the stored on-chain price is slightly outdated until someone interacts with the protocol. These methods let you fetch the raw rate configuration and calculate the exact real-time exchange price locally, which is useful for accurate dashboards and avoiding stale data.
Copy
Ask AI
// Fetch the raw configuration for a tokenconst config = await client.liquidity.getExchangePricesAndConfig(USDC);// Calculate the real-time exchange prices locally based on accrued interestconst { supplyExchangePrice, borrowExchangePrice } = client.liquidity.calculateExchangePrice(config);console.log(`Supply Exchange Price: ${supplyExchangePrice.toString()}`);
This is the core method for building APY aggregators and TVL dashboards. It fetches comprehensive market data including supplyRate and borrowRate (to determine APYs in basis points), lastStoredUtilization (to see how much capital is being borrowed), and total supply/borrow metrics. You can fetch a single token or all tokens simultaneously.
Copy
Ask AI
import { PublicKey } from "@solana/web3.js";const USDC = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");// Fetch single token dataconst data = await client.liquidity.getOverallTokenData(USDC);// Or fetch all tokens at once for efficiency// const allData = await client.liquidity.getAllOverallTokensData();const supplyApr = Number(data.supplyRate) / 100;const borrowApr = Number(data.borrowRate) / 100;const utilization = Number(data.lastStoredUtilization) / 100;console.log(`USDC Supply APR: ${supplyApr}% | Utilization: ${utilization}%`);
These methods return a specific user’s exact balance for a given token. The returned supply or borrow amounts are already adjusted by real-time exchange prices, meaning they accurately reflect any interest earned or owed. They also return expanding limits dictating how much liquidity the user can instantly move.
Copy
Ask AI
const userWallet = new PublicKey("YOUR_WALLET_PUBKEY");// Query a user's supply position for USDCconst { userSupplyData } = await client.liquidity.getUserSupplyData(userWallet, USDC);console.log(`Supplied USDC: ${userSupplyData.supply.toString()}`);// Query a user's borrow position for USDCconst { userBorrowData } = await client.liquidity.getUserBorrowData(userWallet, USDC);console.log(`Borrowed USDC: ${userBorrowData.borrow.toString()}`);
Instead of making dozens of RPC requests to check a user’s balance for every token, batch them. This optimised method fetches a user’s entire portfolio (multiple supply and borrow positions across different tokens) in a single RPC call, reducing load times for user-facing dashboards.
Copy
Ask AI
const SOL = new PublicKey("So11111111111111111111111111111111111111112");// Provide the arrays of tokens the user might be supplying or borrowingconst supplyTokens = [USDC, SOL];const borrowTokens = [USDC];const portfolio = await client.liquidity.getUserMultipleBorrowSupplyData( userWallet, supplyTokens, borrowTokens);console.log("Supplies:", portfolio.userSuppliesData);console.log("Borrows:", portfolio.userBorrowingsData);
This method is for analytics indexers or liquidator bots that need to map out the entire state of the protocol. It fetches every single active user position (supply and borrow) across the entire Liquidity protocol, allowing you to find the largest suppliers or identify at-risk positions globally.
Copy
Ask AI
// Fetch every active position in the protocolconst allPositions = await client.liquidity.getAllUserPositions();console.log(`Found ${allPositions.length} active positions across Jupiter Lend.`);// Example: Find the top 5 largest USDC borrowers// (Requires filtering the returned data by token and sorting)