Learn how to discover and access reserves in Aave v4 spokes.
Reserve data provides comprehensive information about each asset's lending and borrowing conditions, including:
Identification: IDs, spoke, chain
Underlying token information
Supply information: APY, liquidity, caps, collateral configuration
Borrow information: APY, available liquidity, utilization rates, caps
Reserve configuration: collateral factor, liquidation bonus, liquidation fee, collateral risk
Reserve status: frozen, paused
User incentives: extra APY and borrow discounts (see Incentive Programs )
User-specific state: balances, borrowable amounts, collateral usage (when user is specified in request)
TypeScript GraphQL Solidity The following TypeScript interfaces illustrate the core Reserve type:
interface Reserve { __typename : "Reserve" ; id : ReserveId ; onChainId : OnChainReserveId ; chain : Chain ; spoke : Spoke ; asset : HubAsset ; summary : ReserveSummary ; settings : ReserveSettings ; status : ReserveStatus ; canBorrow : boolean ; canSupply : boolean ; canUseAsCollateral : boolean ; canSwapFrom : boolean ; userState : ReserveUserState | null ; }
Listing Available Reserves
Discover all available reserves given some criteria.
React TypeScript GraphQL Solidity Use the useReserves hook (or the imperative useReservesAction variant) to fetch a list of reserves.
import { type ReservesRequest , useReserves } from "@aave/react" ;
function ReservesList ( { request } : { request : ReservesRequest } ) { const { data , loading , error } = useReserves ( request ) ;
if ( loading ) return < div > Loading… </ div > ;
if ( error ) return < div > Error: { error . message } </ div > ;
return ( < div > { data . map ( ( reserve ) => ( < div key = { reserve . id } > < h3 > { reserve . asset . underlying . info . name } </ h3 > < p > Spoke: { reserve . spoke . name } </ p > </ div > ) ) } </ div > ) ; } The useReservesAction hook does not watch for updates. Use it when you
need on-demand, fresh data (e.g., in an event handler).
You can query reserves as follows.
import { chainId } from "@aave/react" ;
const request : ReservesRequest = { query : { chainIds : [ chainId ( 1 ) ] , } , } ; Filter reserves by supply, borrow, or collateral.
import { ReservesRequestFilter } from "@aave/react" ;
const request : ReservesRequest = { query : { } , filter : ReservesRequestFilter . Supply , } ; Add a user address to return ReserveUserState for each reserve.
import { evmAddress } from "@aave/react" ;
const request : ReservesRequest = { query : { } , user : evmAddress ( "0x456…" ) , } ; Sort reserves by asset name, user balance, APYs, collateral factor, or available amounts.
import { OrderDirection } from "@aave/react" ;
const request : ReservesRequest = { query : { } , orderBy : { assetName : OrderDirection . Asc } , } ; Specify a different currency to return fiat amounts in.
import { Currency } from "@aave/react" ;
const { data , error , loading } = useReserves ( { query : { } , currency : Currency . Eur , } ) ;
Fetching a Single Reserve
Get detailed information about a specific reserve.
Use the useReserve hook to fetch a specific reserve.
import { type ReserveRequest , useReserve } from "@aave/react" ;
function ReserveDetails ( { request } : { request : ReserveRequest } ) { const { data , loading , error } = useReserve ( request ) ;
if ( loading ) return < p > Loading reserve... </ p > ;
if ( error ) return < p > Error: { error . message } </ p > ;
if ( ! data ) return < p > Reserve not found </ p > ;
return ( < div > < h2 > Reserve ID: { data . id } </ h2 > < p > Supply APY: { data . summary . supplyApy . normalized . toFixed ( 2 ) } % </ p > < p > Borrow APY: { data . summary . borrowApy . normalized . toFixed ( 2 ) } % </ p > </ div > ) ; } See below for examples of ReserveRequest objects.
import { chainId , evmAddress , type OnChainReserveId } from "@aave/react" ;
const request : ReserveRequest = { query : { reserveInput : { chainId : chainId ( 1 ) , spoke : evmAddress ( "0x123…" ) , onChainId : "1" as OnChainReserveId , } , } , } ; Include user-specific state for the reserve.
import { evmAddress } from "@aave/react" ;
const request : ReserveRequest = { query : { } , user : evmAddress ( "0x456…" ) , } ; Finally, you can specify a different time window or currency for the data.
import { TimeWindow } from "@aave/react" ;
const { data , loading , error } = useReserve ( { query : { } , timeWindow : TimeWindow . LastWeek , } ) ;
Fetch historical borrow APY data for a specific reserve. By default, Merkl rewards are included in the returned rates; pass includeRewards: false for protocol base rates only.
Use the useBorrowApyHistory hook to fetch borrow APY history over time.
import { type BorrowApyHistoryRequest , useBorrowApyHistory } from "@aave/react" ;
function BorrowApy ( { request } : { request : BorrowApyHistoryRequest } ) { const { data , loading , error } = useBorrowApyHistory ( request ) ;
if ( loading ) return < div > Loading… </ div > ;
if ( error ) return < div > Error: { error . message } </ div > ;
return ( < div > { data . map ( ( sample ) => ( < div key = { sample . date . toString ( ) } > < p > < small > { sample . date . toLocaleDateString ( ) } </ small > { sample . avgRate . normalized . toFixed ( 2 ) } % </ p > </ div > ) ) } </ div > ) ; } See below for examples of BorrowApyHistoryRequest objects.
import { TimeWindow } from "@aave/react" ;
const request : BorrowApyHistoryRequest = { reserve : reserve . id , window : TimeWindow . LastDay , } ;
Fetch historical supply APY data for a specific reserve. By default, Merkl rewards are included in the returned rates; pass includeRewards: false for protocol base rates only.
Use the useSupplyApyHistory hook to fetch supply APY history over time.
import { type SupplyApyHistoryRequest , useSupplyApyHistory } from "@aave/react" ;
function SupplyApy ( { request } : { request : SupplyApyHistoryRequest } ) { const { data , loading , error } = useSupplyApyHistory ( request ) ;
if ( loading ) return < div > Loading… </ div > ;
if ( error ) return < div > Error: { error . message } </ div > ;
return ( < div > { data . map ( ( sample ) => ( < div key = { sample . date . toString ( ) } > < p > < small > { sample . date . toLocaleDateString ( ) } </ small > { sample . avgRate . normalized . toFixed ( 2 ) } % </ p > </ div > ) ) } </ div > ) ; } See below for examples of SupplyApyHistoryRequest objects.
import { TimeWindow } from "@aave/react" ;
const request : SupplyApyHistoryRequest = { reserve : reserve . id , window : TimeWindow . LastDay , } ;
Fetch a paginated list of the top holders for a specific reserve, filtered by suppliers or borrowers.
Use the useReserveHolders hook to fetch reserve holders for a specific reserve.
import { ReserveHoldersFilter , useReserveHolders } from "@aave/react" ;
function ReserveHoldersList ( { reserveId } : { reserveId : string } ) { const { data , loading , error } = useReserveHolders ( { reserve : { reserveId } , filter : ReserveHoldersFilter . Supplied , } ) ;
if ( loading ) return < div > Loading… </ div > ;
if ( error ) return < div > Error: { error . message } </ div > ;
return ( < div > { data . items . map ( ( holder ) => ( < div key = { holder . address } > < p > { holder . address } </ p > < p > { holder . amount . amount . value . toFixed ( 4 ) } { " " } { holder . amount . token . info . symbol } </ p > < p > { holder . weight . normalized . toFixed ( 4 ) } % </ p > </ div > ) ) } </ div > ) ; } Filter by ReserveHoldersFilter.Supplied (default) or ReserveHoldersFilter.Borrowed .
import { ReserveHoldersFilter , useReserveHolders } from "@aave/react" ;
const { data } = useReserveHolders ( { reserve : { reserveId : reserve . id } , filter : ReserveHoldersFilter . Supplied , } ) ;