@panoptic-eng/sdk 1.0.69 → 1.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -29,8 +29,16 @@ const providerAbi$1 = parseAbi(["function getPoolDataProvider() view returns (ad
29
29
  const dataAbi = parseAbi([
30
30
  "function getAllReservesTokens() view returns ((string symbol, address tokenAddress)[])",
31
31
  "function getAllATokens() view returns ((string symbol, address tokenAddress)[])",
32
- "function getUserReserveData(address asset, address user) view returns (uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint40,bool)"
32
+ "function getUserReserveData(address asset, address user) view returns (uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint40,bool)",
33
+ "function getReserveData(address asset) view returns (uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint40)"
33
34
  ]);
35
+ const RAY = 10n ** 27n;
36
+ const SECONDS_PER_YEAR$4 = 31536e3;
37
+ /** Aave rates are per-second-compounded APRs in ray; convert to an APY in percent. */
38
+ function rayAprToApyPct(rate) {
39
+ const apr = Number(rate * 1000000n / RAY) / 1e6;
40
+ return ((1 + apr / SECONDS_PER_YEAR$4) ** SECONDS_PER_YEAR$4 - 1) * 100;
41
+ }
34
42
  const oracleAbi$1 = parseAbi(["function BASE_CURRENCY_UNIT() view returns (uint256)", "function getAssetPrice(address asset) view returns (uint256)"]);
35
43
  /** Reads accrued Aave V3 balances and oracle prices at a single block. */
36
44
  async function getAaveHoldings({ client, provider: provider$1, account }) {
@@ -79,28 +87,39 @@ async function getAaveHoldings({ client, provider: provider$1, account }) {
79
87
  args: [reserve.tokenAddress, account]
80
88
  }))
81
89
  });
82
- const balances = rawBalances.map(([supplied, stableDebt, variableDebt]) => [
90
+ const balances = rawBalances.map(([supplied, stableDebt, variableDebt, , , stableBorrowRate]) => [
83
91
  normalizeUnsignedBigInt(supplied),
84
92
  normalizeUnsignedBigInt(stableDebt),
85
- normalizeUnsignedBigInt(variableDebt)
93
+ normalizeUnsignedBigInt(variableDebt),
94
+ normalizeUnsignedBigInt(stableBorrowRate)
86
95
  ]);
87
96
  const holdings = await Promise.all(reserves.flatMap((reserve, i) => {
88
- const [supplied, stableDebt, variableDebt] = balances[i];
97
+ const [supplied, stableDebt, variableDebt, stableBorrowRate] = balances[i];
89
98
  const debt = stableDebt + variableDebt;
90
99
  if (supplied === 0n && debt === 0n) return [];
91
100
  return [(async () => {
92
- const [rawDecimals, rawPrice] = await Promise.all([client.readContract({
93
- address: reserve.tokenAddress,
94
- abi: erc20Abi,
95
- functionName: "decimals",
96
- blockNumber
97
- }), client.readContract({
98
- address: oracle,
99
- abi: oracleAbi$1,
100
- functionName: "getAssetPrice",
101
- args: [reserve.tokenAddress],
102
- blockNumber
103
- })]);
101
+ const [rawDecimals, rawPrice, reserveData] = await Promise.all([
102
+ client.readContract({
103
+ address: reserve.tokenAddress,
104
+ abi: erc20Abi,
105
+ functionName: "decimals",
106
+ blockNumber
107
+ }),
108
+ client.readContract({
109
+ address: oracle,
110
+ abi: oracleAbi$1,
111
+ functionName: "getAssetPrice",
112
+ args: [reserve.tokenAddress],
113
+ blockNumber
114
+ }),
115
+ client.readContract({
116
+ address: dataProvider,
117
+ abi: dataAbi,
118
+ functionName: "getReserveData",
119
+ args: [reserve.tokenAddress],
120
+ blockNumber
121
+ })
122
+ ]);
104
123
  const decimals = normalizeTokenDecimals(rawDecimals);
105
124
  const price = normalizeUnsignedBigInt(rawPrice);
106
125
  return {
@@ -110,7 +129,15 @@ async function getAaveHoldings({ client, provider: provider$1, account }) {
110
129
  supplied,
111
130
  debt,
112
131
  price,
113
- priceUnit
132
+ priceUnit,
133
+ supplyApyPct: rayAprToApyPct(normalizeUnsignedBigInt(reserveData[5])),
134
+ borrowApyPct: (() => {
135
+ const variableApy = rayAprToApyPct(normalizeUnsignedBigInt(reserveData[6]));
136
+ if (stableDebt === 0n) return variableApy;
137
+ const stableApy = rayAprToApyPct(stableBorrowRate);
138
+ const stableWeight = Number(stableDebt * 1000000n / debt) / 1e6;
139
+ return stableApy * stableWeight + variableApy * (1 - stableWeight);
140
+ })()
114
141
  };
115
142
  })()];
116
143
  }));
@@ -134,7 +161,11 @@ const responseSchema = z.object({ data: z.object({ marketPositions: z.object({ i
134
161
  market: z.object({
135
162
  marketId: z.string(),
136
163
  loanAsset: asset,
137
- collateralAsset: asset.nullable()
164
+ collateralAsset: asset.nullable(),
165
+ state: z.object({
166
+ supplyApy: z.number().finite().nullable(),
167
+ borrowApy: z.number().finite().nullable()
168
+ }).nullable().optional()
138
169
  }),
139
170
  state: z.object({
140
171
  supplyAssets: amount,
@@ -154,7 +185,8 @@ async function getMorphoHoldings(account, chainId) {
154
185
  query: `query Positions($account: [String!], $chains: [Int!], $skip: Int!) {
155
186
  marketPositions(first: 100, skip: $skip, where: {userAddress_in: $account, chainId_in: $chains}) {
156
187
  items { market { marketId loanAsset { address symbol decimals price { usd } }
157
- collateralAsset { address symbol decimals price { usd } } }
188
+ collateralAsset { address symbol decimals price { usd } }
189
+ state { supplyApy borrowApy } }
158
190
  state { supplyAssets borrowAssets collateral } }
159
191
  }
160
192
  }`,
@@ -170,21 +202,25 @@ async function getMorphoHoldings(account, chainId) {
170
202
  if (typeof body === "object" && body !== null && "errors" in body) throw new Error("Morpho query failed");
171
203
  const items = responseSchema.parse(body).data.marketPositions.items;
172
204
  for (const { market, state } of items) {
205
+ const pct = (apy) => apy == null ? null : apy * 100;
173
206
  const legs = [
174
207
  {
175
208
  token: market.loanAsset,
176
209
  amount: state.supplyAssets,
177
- kind: "supply"
210
+ kind: "supply",
211
+ apyPct: pct(market.state?.supplyApy)
178
212
  },
179
213
  {
180
214
  token: market.loanAsset,
181
215
  amount: -state.borrowAssets,
182
- kind: "debt"
216
+ kind: "debt",
217
+ apyPct: pct(market.state?.borrowApy)
183
218
  },
184
219
  {
185
220
  token: market.collateralAsset,
186
221
  amount: state.collateral,
187
- kind: "collateral"
222
+ kind: "collateral",
223
+ apyPct: 0
188
224
  }
189
225
  ];
190
226
  for (const leg of legs) {
@@ -194,6 +230,7 @@ async function getMorphoHoldings(account, chainId) {
194
230
  ...leg.token,
195
231
  amount: leg.amount,
196
232
  kind: leg.kind,
233
+ apyPct: leg.apyPct,
197
234
  marketId: market.marketId,
198
235
  priceUsd: leg.token.price?.usd?.toString() ?? null
199
236
  });