User Positions

Learn how to fetch and monitor user positions on Aave v4.


Each user position captures a user’s activity within a Spoke, simplifying health and performance tracking.

User Positions

Data Structure

User position data provides comprehensive information about a user's lending and borrowing activity on a specific spoke, including:

  • Identification: id, user, spoke

  • Position balances: supplied amounts, collateral amounts, debt amounts, net balances

  • Yield information: supply APY, borrow APY, net APY

  • Risk metrics: health factor, risk premium

  • Performance data: net balance percentage changes over time

The following TypeScript interfaces illustrate the core UserPosition type:

interface UserPosition {  __typename: "UserPosition";  id: UserPositionId;  user: EvmAddress;  spoke: Spoke;  totalSupplied: FiatAmountWithChange;  totalCollateral: FiatAmountWithChange;  totalDebt: FiatAmountWithChange;  netBalance: FiatAmountWithChange;  netCollateral: FiatAmountWithChange;  netApy: PercentNumber;  netSupplyApy: PercentNumberWithChange;  netBorrowApy: PercentNumberWithChange;  healthFactor: HealthFactorWithChange;  riskPremium: PercentNumber;  betterRiskPremium?: PercentNumber;  averageCollateralFactor: PercentNumber;}

See the Spoke Data Structure for more details.

Listing User Positions

Fetch all user positions with filtering and ordering options.

Use the useUserPositions hook to fetch positions for a given user address.

import { type UserPositionsRequest, useUserPositions } from "@aave/react";
function UserPositionsList({ request }: { request: UserPositionsRequest }) {  const { data, loading, error } = useUserPositions(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (    <div>      {data.map((position) => (        <div key={position.id}>          <h3>Position on {position.spoke.name}</h3>          <p>Chain: {position.spoke.chain.name}</p>        </div>      ))}    </div>  );}

You can filter positions by the following criteria:

import { evmAddress, chainId } from "@aave/react";
const { data, error, loading } = useUserPositions({  user: evmAddress("0x456…"),  filter: { chainIds: [chainId(1)] },});

And you can sort positions as follows:

import { evmAddress, chainId, OrderDirection } from "@aave/react";
const { data, error, loading } = useUserPositions({  user: evmAddress("0x456…"),  filter: { chainIds: [chainId(1)] },  orderBy: { balance: OrderDirection.Asc },});

Finally, you can specify a different time window or currency for the data.

import { evmAddress, chainId, TimeWindow } from "@aave/react";
const { data, error, loading } = useUserPositions({  user: evmAddress("0x456…"),  filter: { chainIds: [chainId(1)] },  timeWindow: TimeWindow.LastWeek,});

Fetching a Single Position

Fetch a specific user position.

Use the useUserPosition hook to fetch a specific user position.

import { type UserPositionRequest, useUserPosition } from "@aave/react";
function UserPositionDetail({ request }: { request: UserPositionRequest }) {  const { data, loading, error } = useUserPosition(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!data) return <div>Position not found</div>;
  return (    <div>      <h2>Position {data.id}</h2>      <p>Net Balance: {data.netBalance.amount.value}</p>      <p>Health Factor: {data.healthFactor.value}</p>    </div>  );}

See below for examples of how to use the useUserPosition hook.

import { evmAddress } from "@aave/react";
const { data, error, loading } = useUserPosition({  userSpoke: {    user: evmAddress("0x456…"),    spoke: spoke.id,  },});

User Supplies

Data Structure

User supply data provides detailed information about individual user supplies within a spoke, including:

  • Reserve details: token information, supply APY, lending limits

  • Position amounts: supplied shares, earned amounts, and token details

  • Collateral status: whether the supply is used as collateral

  • Performance metrics: earned interest over time

The following TypeScript interfaces illustrate the UserSupplyItem type:

UserSupplyItem
interface UserSupplyItem {  __typename: "UserSupplyItem";  id: UserSupplyItemId;  reserve: Reserve;  principal: Erc20Amount;  withdrawable: Erc20Amount;  interest: Erc20Amount;  isCollateral: boolean;}

See the Reserve Data Structure for more details.

Fetching User Supplies

Fetch user supplies within a specific spoke.

Use the useUserSupplies hook to fetch user supplies for a user.

import { type UserSuppliesRequest, useUserSupplies } from "@aave/react";
function UserSuppliesList({ request }: { request: UserSuppliesRequest }) {  const { data, loading, error } = useUserSupplies(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (    <div>      {data.map((supply) => (        <div key={supply.id}>          <h3>{supply.reserve.asset.underlying.info.name}</h3>          <p>Amount: {supply.withdrawable.amount.value.toDisplayString(2)}</p>        </div>      ))}    </div>  );}

See below for examples of how to use the useUserSupplies hook.

const { data, error, loading } = useUserSupplies({  query: {    userPositionId: position.id,  },});

Sort user supplies by asset name, amount, or supply APY.

import { OrderDirection } from "@aave/react";
const { data, error, loading } = useUserSupplies({  query: {    // your query criteria  },  orderBy: { assetName: OrderDirection.Asc },});

Specify a different currency for displaying fiat amounts.

Custom Currency
import { Currency } from "@aave/react";
const { data, error, loading } = useUserSupplies({  query: {    // your query criteria  },  currency: Currency.Eur,});

Include zero-value entries for all other supply reserves available on the same spoke, typically ordered by descending amount.

Include Zero Balances
import { OrderDirection } from "@aave/react";
const { data, error, loading } = useUserSupplies({  query: {    // your query criteria  },  includeZeroBalances: true,  orderBy: { amount: OrderDirection.Desc },});

User Borrows

Data Structure

User borrow data provides detailed information about individual borrow positions within a spoke, including:

  • Reserve details: token information, borrow APY, borrowing limits

  • Position amounts: borrowed amounts, repaid amounts, and token details

  • Debt tracking: outstanding debt and payment history

  • Performance metrics: interest owed and payment progress

The following TypeScript interfaces illustrate the UserBorrowItem type:

UserBorrowItem
interface UserBorrowItem {  __typename: "UserBorrowItem";  id: UserBorrowItemId;  reserve: Reserve;  principal: Erc20Amount;  debt: Erc20Amount;  interest: Erc20Amount;}

See the Reserve Data Structure for more details.

Fetching User Borrows

Fetch user borrows within a specific spoke.

Use the useUserBorrows hook to fetch borrow positions for a user.

import { type UserBorrowsRequest, useUserBorrows } from "@aave/react";
function UserBorrowsList({ request }: { request: UserBorrowsRequest }) {  const { data, loading, error } = useUserBorrows(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (    <div>      {data.map((borrow) => (        <div key={borrow.id}>          <h3>{borrow.reserve.asset.underlying.info.name}</h3>          <p>Amount: {borrow.debt.amount.value.toDisplayString(2)}</p>        </div>      ))}    </div>  );}

See below for examples of how to use the useUserBorrows hook.

const { data, error, loading } = useUserBorrows({  query: {    userPositionId: position.id,  },});

Sort user borrows by asset name, amount, or borrow APY.

import { OrderDirection } from "@aave/react";
const { data, error, loading } = useUserBorrows({  query: {    // your query criteria  },  orderBy: { assetName: OrderDirection.Asc },});

Specify a different currency for displaying fiat amounts.

Custom Currency
import { Currency } from "@aave/react";
const { data, error, loading } = useUserBorrows({  query: {    // your query criteria  },  currency: Currency.Eur,});

Include zero-value entries for all other borrow reserves available on the same spoke, typically ordered by descending amount.

Include Zero Balances
import { OrderDirection } from "@aave/react";
const { data, error, loading } = useUserBorrows({  query: {    // your query criteria  },  includeZeroBalances: true,  orderBy: { amount: OrderDirection.Desc },});

User Summary

Data Structure

User summary data provides comprehensive information about a user's aggregated activity across all positions, including:

  • Position count: total number of positions held by the user

  • Portfolio totals: supplied amounts, collateral amounts, debt amounts, net balances

  • Yield information: calculated net APY across all positions

  • Risk metrics: lowest health factor across all positions

  • Performance data: net fee earned over time

The following TypeScript interfaces illustrate the UserSummary type:

interface UserSummary {  __typename: "UserSummary";  totalPositions: number;  netBalance: FiatAmountWithChange;  totalCollateral: FiatAmount;  totalSupplied: FiatAmount;  totalDebt: FiatAmount;  netApy: PercentNumber;  netFeeEarned: FiatAmount;  lowestHealthFactor: BigDecimal | null;}

Fetching User Summary

Fetch a comprehensive financial summary for a user across all their positions.

Use the useUserSummary hook to fetch the financial summary for a user.

import { type UserSummaryRequest, useUserSummary } from "@aave/react";
function UserSummaryDisplay({ request }: { request: UserSummaryRequest }) {  const { data, loading, error } = useUserSummary(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (    <div>      <h2>Financial Summary</h2>      <p>Total Positions: {data.totalPositions}</p>      <p>        Net Balance: {data.netBalance.current.symbol}        {data.netBalance.current.value}      </p>      <p>        Total Supplied: {data.totalSupplied.symbol}        {data.totalSupplied.value}      </p>      <p>        Total Debt: {data.totalDebt.symbol}        {data.totalDebt.value}      </p>      <p>Net APY: {data.netApy.normalized.toFixed(2)}%</p>    </div>  );}

See below for examples of how to use the useUserSummary hook.

import { evmAddress } from "@aave/react";
const { data, error, loading } = useUserSummary({  user: evmAddress("0x456…"),});

Specify a different time window to calculate net balance changes over different periods.

Custom Time Window
import { TimeWindow } from "@aave/react";
const { data, error, loading } = useUserSummary({  user: evmAddress("0x456…"),  timeWindow: TimeWindow.LastWeek,});

Specify a different currency for displaying fiat amounts.

Custom Currency
import { Currency, useUserSummary } from "@aave/react";
const { data, error, loading } = useUserSummary({  user: evmAddress("0x456…"),  currency: Currency.Eur,});

User Summary History

Data Structure

User summary history data provides detailed information about a user's activity changes over time, including:

  • Historical snapshots: portfolio state at different points in time

  • Portfolio metrics: net balance, borrows, supplies at each snapshot

  • Risk metrics: health factor changes over time

The following TypeScript interfaces illustrate the UserSummaryHistoryItem type:

UserSummaryHistoryItem
interface UserSummaryHistoryItem {  __typename: "UserSummaryHistoryItem";  netBalance: FiatAmount;  borrows: FiatAmount;  supplies: FiatAmount;  healthFactor: BigDecimal | null;  date: Date;}

Fetching User Summary History

Fetch historical financial data for a user over a specified time window.

Use the useUserSummaryHistory hook to fetch historical financial data for a user.

import {  type UserSummaryHistoryRequest,  useUserSummaryHistory,} from "@aave/react";
function UserSummaryHistoryChart({  request,}: {  request: UserSummaryHistoryRequest;}) {  const { data, loading, error } = useUserSummaryHistory(request);
  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (    <div>      <h2>Financial History</h2>      {data.map((item) => (        <div key={item.date.toString()}>          <p>Date: {item.date.toLocaleDateString()}</p>          <p>            Net Balance: {item.netBalance.symbol}            {item.netBalance.value.toDisplayString(2)}          </p>          <p>            Supplies: {item.supplies.symbol}            {item.supplies.value.toDisplayString(2)}          </p>          <p>            Borrows: {item.borrows.symbol}            {item.borrows.value.toDisplayString(2)}          </p>        </div>      ))}    </div>  );}

See below for examples of how to use the useUserSummaryHistory hook.

import { evmAddress, TimeWindow } from "@aave/react";
const { data, error, loading } = useUserSummaryHistory({  user: evmAddress("0x456…"),  window: TimeWindow.LastDay,});

Filter the history by specific spokes or chains.

import { evmAddress, TimeWindow } from "@aave/react";
const { data, error, loading } = useUserSummaryHistory({  user: evmAddress("0x456…"),  window: TimeWindow.LastWeek,  filter: {    spokeId: spoke.id,  },});

Specify a different currency for displaying fiat amounts.

Custom Currency
import { Currency, evmAddress, TimeWindow } from "@aave/react";
const { data, error, loading } = useUserSummaryHistory({  user: evmAddress("0x456…"),  window: TimeWindow.LastWeek,  currency: Currency.Eur,});