Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/wicked-mugs-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@aave/graphql": minor
"@aave/client": minor
---

feat: expose user earned/debt APY in MarketUserState
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ examples/*/pnpm-lock.yaml

# local env files
.env
.env.local

# typescript
*.tsbuildinfo

# test results
reports/


21 changes: 10 additions & 11 deletions packages/client/src/actions/markets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UnexpectedError } from '@aave/core';
import type { UnexpectedError } from "@aave/core";
import {
type Market,
MarketQuery,
Expand All @@ -8,14 +8,13 @@ import {
OrderDirection,
UserMarketStateQuery,
type UserMarketStateRequest,
} from '@aave/graphql';
import type { ChainId, EvmAddress, ResultAsync } from '@aave/types';
import type { AaveClient } from '../AaveClient';
} from "@aave/graphql";
import type { ChainId, EvmAddress, ResultAsync } from "@aave/types";
import type { AaveClient } from "../AaveClient";

export const defaultMarketReservesRequestOrderBy: MarketReservesRequestOrderBy =
{
tokenName: OrderDirection.Asc,
};
export const defaultMarketReservesRequestOrderBy: MarketReservesRequestOrderBy = {
tokenName: OrderDirection.Asc,
};

export type MarketsRequest = {
/**
Expand Down Expand Up @@ -62,7 +61,7 @@ export function markets(
borrowsOrderBy = defaultMarketReservesRequestOrderBy,
suppliesOrderBy = defaultMarketReservesRequestOrderBy,
user,
}: MarketsRequest,
}: MarketsRequest
): ResultAsync<Market[], UnexpectedError> {
return client.query(MarketsQuery, {
request: { chainIds, user },
Expand Down Expand Up @@ -123,7 +122,7 @@ export function market(
user,
borrowsOrderBy = defaultMarketReservesRequestOrderBy,
suppliesOrderBy = defaultMarketReservesRequestOrderBy,
}: MarketRequest,
}: MarketRequest
): ResultAsync<Market | null, UnexpectedError> {
return client.query(MarketQuery, {
request: { address, chainId, user },
Expand All @@ -149,7 +148,7 @@ export function market(
*/
export function userMarketState(
client: AaveClient,
request: UserMarketStateRequest,
request: UserMarketStateRequest
): ResultAsync<MarketUserState, UnexpectedError> {
return client.query(UserMarketStateQuery, { request });
}
8 changes: 7 additions & 1 deletion packages/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,12 @@ type MarketUserState {
"""The user's net annual percentage yield across all positions"""
netAPY: PercentValue!

"""The user's earned annual percentage yield across all supply positions"""
userEarnedAPY: PercentValue!

"""The user's debt annual percentage yield across all borrow positions"""
userDebtAPY: PercentValue!

"""
The user's health factor (risk metric for liquidation) - if null, the user does not have a borrow
"""
Expand Down Expand Up @@ -679,7 +685,7 @@ enum OperationType {
VAULT_FEE_UPDATED
VAULT_FEE_WITHDRAWN
VAULT_WITHDRAW
VAULT_TRANSFER
VAULT_OWNERSHIP_TRANSFERRED
REVENUE_SPLITTER_OWNER_DEPLOYED
REVENUE_SPLITTER_OWNER_TRANSFER
LIQUIDATION
Expand Down
171 changes: 88 additions & 83 deletions packages/graphql/src/fragments/market.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,108 @@
import type { FragmentOf } from 'gql.tada';
import { graphql } from '../graphql';
import { ChainFragment } from './chain';
import { CurrencyFragment, PercentValueFragment } from './common';
import { ReserveFragment } from './reserve';
import type { FragmentOf } from "gql.tada";
import { graphql } from "../graphql";
import { ChainFragment } from "./chain";
import { CurrencyFragment, PercentValueFragment } from "./common";
import { ReserveFragment } from "./reserve";

export const MarketUserStateFragment = graphql(
`fragment MarketUserState on MarketUserState {
__typename
netWorth
netAPY {
...PercentValue
`
fragment MarketUserState on MarketUserState {
__typename
netWorth
netAPY {
...PercentValue
}
userEarnedAPY {
...PercentValue
}
userDebtAPY {
...PercentValue
}
healthFactor
eModeEnabled
totalCollateralBase
totalDebtBase
availableBorrowsBase
currentLiquidationThreshold {
...PercentValue
}
ltv {
...PercentValue
}
isInIsolationMode
}
healthFactor
eModeEnabled
totalCollateralBase
totalDebtBase
availableBorrowsBase
currentLiquidationThreshold {
...PercentValue
}
ltv {
...PercentValue
}
isInIsolationMode
}`,
[PercentValueFragment],
`,
[PercentValueFragment]
);
export type MarketUserState = FragmentOf<typeof MarketUserStateFragment>;

export const EmodeMarketReserveInfoFragment = graphql(
`fragment EmodeMarketReserveInfo on EmodeMarketReserveInfo {
__typename
underlyingToken {
...Currency
`
fragment EmodeMarketReserveInfo on EmodeMarketReserveInfo {
__typename
underlyingToken {
...Currency
}
canBeCollateral
canBeBorrowed
}
canBeCollateral
canBeBorrowed
}`,
[CurrencyFragment],
`,
[CurrencyFragment]
);
export type EmodeMarketReserveInfo = FragmentOf<
typeof EmodeMarketReserveInfoFragment
>;
export type EmodeMarketReserveInfo = FragmentOf<typeof EmodeMarketReserveInfoFragment>;

export const EmodeMarketCategoryFragment = graphql(
`fragment EmodeMarketCategory on EmodeMarketCategory {
__typename
id
label
maxLTV {
...PercentValue
}
liquidationThreshold {
...PercentValue
}
liquidationPenalty {
...PercentValue
}
reserves {
...EmodeMarketReserveInfo
`
fragment EmodeMarketCategory on EmodeMarketCategory {
__typename
id
label
maxLTV {
...PercentValue
}
liquidationThreshold {
...PercentValue
}
liquidationPenalty {
...PercentValue
}
reserves {
...EmodeMarketReserveInfo
}
}
}`,
[PercentValueFragment, EmodeMarketReserveInfoFragment],
`,
[PercentValueFragment, EmodeMarketReserveInfoFragment]
);
export type EmodeMarketCategory = FragmentOf<
typeof EmodeMarketCategoryFragment
>;
export type EmodeMarketCategory = FragmentOf<typeof EmodeMarketCategoryFragment>;

export const MarketFragment = graphql(
`fragment Market on Market {
__typename
name
chain {
...Chain
}
address
icon
totalMarketSize
totalAvailableLiquidity
eModeCategories {
...EmodeMarketCategory
}
userState {
...MarketUserState
}
`
fragment Market on Market {
__typename
name
chain {
...Chain
}
address
icon
totalMarketSize
totalAvailableLiquidity
eModeCategories {
...EmodeMarketCategory
}
userState {
...MarketUserState
}

borrowReserves: reserves(request: { reserveType: BORROW, orderBy: $borrowsOrderBy }) {
...Reserve
}
borrowReserves: reserves(request: { reserveType: BORROW, orderBy: $borrowsOrderBy }) {
...Reserve
}

supplyReserves: reserves(request: { reserveType: SUPPLY, orderBy: $suppliesOrderBy }) {
...Reserve
supplyReserves: reserves(request: { reserveType: SUPPLY, orderBy: $suppliesOrderBy }) {
...Reserve
}
}
}`,
[
ChainFragment,
EmodeMarketCategoryFragment,
ReserveFragment,
MarketUserStateFragment,
],
`,
[ChainFragment, EmodeMarketCategoryFragment, ReserveFragment, MarketUserStateFragment]
);
export type Market = FragmentOf<typeof MarketFragment>;
4 changes: 2 additions & 2 deletions packages/graphql/src/graphql-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ export type introspection_types = {
'MarketReservesRequestType': { name: 'MarketReservesRequestType'; enumValues: 'SUPPLY' | 'BORROW' | 'BOTH'; };
'MarketUserReserveBorrowPosition': { kind: 'OBJECT'; name: 'MarketUserReserveBorrowPosition'; fields: { 'apy': { name: 'apy'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'currency': { name: 'currency'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Currency'; ofType: null; }; } }; 'debt': { name: 'debt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'TokenAmount'; ofType: null; }; } }; 'market': { name: 'market'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'MarketInfo'; ofType: null; }; } }; }; };
'MarketUserReserveSupplyPosition': { kind: 'OBJECT'; name: 'MarketUserReserveSupplyPosition'; fields: { 'apy': { name: 'apy'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'balance': { name: 'balance'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'TokenAmount'; ofType: null; }; } }; 'canBeCollateral': { name: 'canBeCollateral'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'currency': { name: 'currency'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Currency'; ofType: null; }; } }; 'isCollateral': { name: 'isCollateral'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'market': { name: 'market'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'MarketInfo'; ofType: null; }; } }; }; };
'MarketUserState': { kind: 'OBJECT'; name: 'MarketUserState'; fields: { 'availableBorrowsBase': { name: 'availableBorrowsBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'currentLiquidationThreshold': { name: 'currentLiquidationThreshold'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'eModeEnabled': { name: 'eModeEnabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'healthFactor': { name: 'healthFactor'; type: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; } }; 'isInIsolationMode': { name: 'isInIsolationMode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'ltv': { name: 'ltv'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'netAPY': { name: 'netAPY'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'netWorth': { name: 'netWorth'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'totalCollateralBase': { name: 'totalCollateralBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'totalDebtBase': { name: 'totalDebtBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; }; };
'MarketUserState': { kind: 'OBJECT'; name: 'MarketUserState'; fields: { 'availableBorrowsBase': { name: 'availableBorrowsBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'currentLiquidationThreshold': { name: 'currentLiquidationThreshold'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'eModeEnabled': { name: 'eModeEnabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'healthFactor': { name: 'healthFactor'; type: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; } }; 'isInIsolationMode': { name: 'isInIsolationMode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'ltv': { name: 'ltv'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'netAPY': { name: 'netAPY'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'netWorth': { name: 'netWorth'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'totalCollateralBase': { name: 'totalCollateralBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'totalDebtBase': { name: 'totalDebtBase'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigDecimal'; ofType: null; }; } }; 'userDebtAPY': { name: 'userDebtAPY'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'userEarnedAPY': { name: 'userEarnedAPY'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; }; };
'MarketsRequest': { kind: 'INPUT_OBJECT'; name: 'MarketsRequest'; isOneOf: false; inputFields: [{ name: 'chainIds'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ChainId'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'user'; type: { kind: 'SCALAR'; name: 'EvmAddress'; ofType: null; }; defaultValue: null }]; };
'MeritBorrowAndSupplyIncentiveCondition': { kind: 'OBJECT'; name: 'MeritBorrowAndSupplyIncentiveCondition'; fields: { 'borrowToken': { name: 'borrowToken'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Currency'; ofType: null; }; } }; 'claimLink': { name: 'claimLink'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'URL'; ofType: null; }; } }; 'extraApr': { name: 'extraApr'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'supplyToken': { name: 'supplyToken'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Currency'; ofType: null; }; } }; }; };
'MeritBorrowIncentive': { kind: 'OBJECT'; name: 'MeritBorrowIncentive'; fields: { 'borrowAprDiscount': { name: 'borrowAprDiscount'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; 'claimLink': { name: 'claimLink'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'URL'; ofType: null; }; } }; }; };
'MeritSupplyIncentive': { kind: 'OBJECT'; name: 'MeritSupplyIncentive'; fields: { 'claimLink': { name: 'claimLink'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'URL'; ofType: null; }; } }; 'extraSupplyApr': { name: 'extraSupplyApr'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PercentValue'; ofType: null; }; } }; }; };
'MessageData': { kind: 'OBJECT'; name: 'MessageData'; fields: { 'deadline': { name: 'deadline'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'nonce': { name: 'nonce'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigInt'; ofType: null; }; } }; 'owner': { name: 'owner'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'EvmAddress'; ofType: null; }; } }; 'spender': { name: 'spender'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'EvmAddress'; ofType: null; }; } }; 'value': { name: 'value'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'BigInt'; ofType: null; }; } }; }; };
'NativeCurrency': { kind: 'OBJECT'; name: 'NativeCurrency'; fields: { 'chainId': { name: 'chainId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ChainId'; ofType: null; }; } }; 'decimals': { name: 'decimals'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'imageUrl': { name: 'imageUrl'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'symbol': { name: 'symbol'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'wrappedToken': { name: 'wrappedToken'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'EvmAddress'; ofType: null; }; } }; }; };
'OperationType': { name: 'OperationType'; enumValues: 'BORROW' | 'REPAY' | 'RESERVE_USED_AS_COLLATERAL_ENABLED' | 'RESERVE_USED_AS_COLLATERAL_DISABLED' | 'SUPPLY' | 'USER_EMODE_SET' | 'WITHDRAW' | 'VAULT_DEPLOYED' | 'VAULT_DEPOSIT' | 'VAULT_FEE_UPDATED' | 'VAULT_FEE_WITHDRAWN' | 'VAULT_WITHDRAW' | 'VAULT_TRANSFER' | 'REVENUE_SPLITTER_OWNER_DEPLOYED' | 'REVENUE_SPLITTER_OWNER_TRANSFER' | 'LIQUIDATION'; };
'OperationType': { name: 'OperationType'; enumValues: 'BORROW' | 'REPAY' | 'RESERVE_USED_AS_COLLATERAL_ENABLED' | 'RESERVE_USED_AS_COLLATERAL_DISABLED' | 'SUPPLY' | 'USER_EMODE_SET' | 'WITHDRAW' | 'VAULT_DEPLOYED' | 'VAULT_DEPOSIT' | 'VAULT_FEE_UPDATED' | 'VAULT_FEE_WITHDRAWN' | 'VAULT_WITHDRAW' | 'VAULT_OWNERSHIP_TRANSFERRED' | 'REVENUE_SPLITTER_OWNER_DEPLOYED' | 'REVENUE_SPLITTER_OWNER_TRANSFER' | 'LIQUIDATION'; };
'OrderDirection': { name: 'OrderDirection'; enumValues: 'ASC' | 'DESC'; };
'PageSize': { name: 'PageSize'; enumValues: 'TEN' | 'FIFTY'; };
'PaginatedResultInfo': { kind: 'OBJECT'; name: 'PaginatedResultInfo'; fields: { 'next': { name: 'next'; type: { kind: 'SCALAR'; name: 'Cursor'; ofType: null; } }; 'prev': { name: 'prev'; type: { kind: 'SCALAR'; name: 'Cursor'; ofType: null; } }; }; };
Expand Down
Loading