@defisaver/positions-sdk 2.1.127-midnight-dev → 2.1.127-midnight-2-dev

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.
Files changed (79) hide show
  1. package/cjs/aaveV3/index.js +7 -1
  2. package/cjs/aaveV4/lend.js +3 -3
  3. package/cjs/claiming/index.d.ts +2 -1
  4. package/cjs/claiming/index.js +3 -1
  5. package/cjs/claiming/uniswap.d.ts +5 -0
  6. package/cjs/claiming/uniswap.js +75 -0
  7. package/cjs/config/contracts.d.ts +22 -0
  8. package/cjs/config/contracts.js +9 -1
  9. package/cjs/contracts.d.ts +35 -0
  10. package/cjs/contracts.js +2 -1
  11. package/cjs/curveUsd/index.js +1 -1
  12. package/cjs/helpers/morphoBlueHelpers/index.js +1 -0
  13. package/cjs/helpers/morphoMidnightHelpers/index.d.ts +62 -0
  14. package/cjs/helpers/morphoMidnightHelpers/index.js +156 -1
  15. package/cjs/llamaLend/index.js +1 -1
  16. package/cjs/markets/aaveV4/index.d.ts +2 -0
  17. package/cjs/markets/aaveV4/index.js +14 -1
  18. package/cjs/morphoBlue/index.d.ts +8 -6
  19. package/cjs/morphoBlue/index.js +69 -40
  20. package/cjs/morphoMidnight/index.js +25 -1
  21. package/cjs/portfolio/index.js +31 -2
  22. package/cjs/savings/summerVaults/options.js +10 -10
  23. package/cjs/staking/staking.js +3 -0
  24. package/cjs/types/aaveV4.d.ts +2 -1
  25. package/cjs/types/aaveV4.js +1 -0
  26. package/cjs/types/claiming.d.ts +10 -0
  27. package/cjs/types/claiming.js +2 -0
  28. package/cjs/types/morphoBlue.d.ts +9 -0
  29. package/cjs/types/morphoMidnight.d.ts +3 -0
  30. package/esm/aaveV3/index.js +7 -1
  31. package/esm/aaveV4/lend.js +3 -3
  32. package/esm/claiming/index.d.ts +2 -1
  33. package/esm/claiming/index.js +2 -1
  34. package/esm/claiming/uniswap.d.ts +5 -0
  35. package/esm/claiming/uniswap.js +67 -0
  36. package/esm/config/contracts.d.ts +22 -0
  37. package/esm/config/contracts.js +8 -0
  38. package/esm/contracts.d.ts +35 -0
  39. package/esm/contracts.js +1 -0
  40. package/esm/curveUsd/index.js +1 -1
  41. package/esm/helpers/morphoBlueHelpers/index.js +1 -0
  42. package/esm/helpers/morphoMidnightHelpers/index.d.ts +62 -0
  43. package/esm/helpers/morphoMidnightHelpers/index.js +149 -0
  44. package/esm/llamaLend/index.js +1 -1
  45. package/esm/markets/aaveV4/index.d.ts +2 -0
  46. package/esm/markets/aaveV4/index.js +12 -0
  47. package/esm/morphoBlue/index.d.ts +8 -6
  48. package/esm/morphoBlue/index.js +62 -39
  49. package/esm/morphoMidnight/index.js +26 -2
  50. package/esm/portfolio/index.js +32 -3
  51. package/esm/savings/summerVaults/options.js +10 -10
  52. package/esm/staking/staking.js +3 -0
  53. package/esm/types/aaveV4.d.ts +2 -1
  54. package/esm/types/aaveV4.js +1 -0
  55. package/esm/types/claiming.d.ts +10 -0
  56. package/esm/types/claiming.js +2 -0
  57. package/esm/types/morphoBlue.d.ts +9 -0
  58. package/esm/types/morphoMidnight.d.ts +3 -0
  59. package/package.json +2 -2
  60. package/src/aaveV3/index.ts +13 -1
  61. package/src/aaveV4/lend.ts +3 -3
  62. package/src/claiming/index.ts +2 -0
  63. package/src/claiming/uniswap.ts +70 -0
  64. package/src/config/contracts.ts +9 -0
  65. package/src/contracts.ts +2 -0
  66. package/src/curveUsd/index.ts +1 -1
  67. package/src/helpers/morphoBlueHelpers/index.ts +1 -0
  68. package/src/helpers/morphoMidnightHelpers/index.ts +206 -0
  69. package/src/llamaLend/index.ts +1 -1
  70. package/src/markets/aaveV4/index.ts +13 -0
  71. package/src/morphoBlue/index.ts +101 -44
  72. package/src/morphoMidnight/index.ts +29 -2
  73. package/src/portfolio/index.ts +32 -3
  74. package/src/savings/summerVaults/options.ts +10 -10
  75. package/src/staking/staking.ts +2 -0
  76. package/src/types/aaveV4.ts +1 -0
  77. package/src/types/claiming.ts +11 -0
  78. package/src/types/morphoBlue.ts +11 -0
  79. package/src/types/morphoMidnight.ts +6 -0
@@ -24,7 +24,7 @@ const getAndFormatBands = async (provider: Client, network: NetworkNumber, selec
24
24
  // getBandsData uses a lot of gas to get all of the bands at once, so we use pagination and fetch 200 bands at a time
25
25
  let i = minBand;
26
26
  while (i < maxBand) {
27
- i += 200;
27
+ i += 20;
28
28
  if (i > maxBand) {
29
29
  pivots.push(maxBand);
30
30
  } else {
@@ -193,6 +193,18 @@ export const AAVE_V4_USDG_PENDLE_SPOKE = (networkId: NetworkNumber): AaveV4Spoke
193
193
  ],
194
194
  });
195
195
 
196
+ export const AAVE_V4_USDG_MAPLE_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
197
+ chainIds: [NetworkNumber.Eth],
198
+ label: 'USDG Maple',
199
+ value: AaveV4SpokesType.AaveV4USDGMapleSpoke,
200
+ url: 'usdg-maple',
201
+ address: '0x774b9655413c34809c1f1b16b654465A89EBE989',
202
+ hubs: [
203
+ AAVE_V4_PAXOS_HUB(NetworkNumber.Eth).address,
204
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
205
+ ],
206
+ });
207
+
196
208
  export const AaveV4Spokes = (networkId: NetworkNumber) => ({
197
209
  [AaveV4SpokesType.AaveV4BluechipSpoke]: AAVE_V4_BLUECHIP_SPOKE(networkId),
198
210
  [AaveV4SpokesType.AaveV4EthenaCorrelatedSpoke]: AAVE_V4_ETHENA_CORRELATED_SPOKE(networkId),
@@ -205,6 +217,7 @@ export const AaveV4Spokes = (networkId: NetworkNumber) => ({
205
217
  [AaveV4SpokesType.AaveV4LombardBtcSpoke]: AAVE_V4_LOMBARD_BTC_SPOKE(networkId),
206
218
  [AaveV4SpokesType.AaveV4MainSpoke]: AAVE_V4_MAIN_SPOKE(networkId),
207
219
  [AaveV4SpokesType.AaveV4USDGPendleSpoke]: AAVE_V4_USDG_PENDLE_SPOKE(networkId),
220
+ [AaveV4SpokesType.AaveV4USDGMapleSpoke]: AAVE_V4_USDG_MAPLE_SPOKE(networkId),
208
221
  }) as const;
209
222
 
210
223
  export const getAaveV4SpokeTypeInfo = (type: AaveV4SpokesType, network?: NetworkNumber) => ({ ...AaveV4Spokes(network ?? NetworkNumber.Eth) }[type]);
@@ -8,7 +8,7 @@ import {
8
8
  DFSFeedRegistryContractViem, FeedRegistryContractViem, MorphoBlueViewContractViem,
9
9
  } from '../contracts';
10
10
  import {
11
- MorphoBlueAssetsData, MorphoBlueMarketData, MorphoBlueMarketInfo, MorphoBluePositionData,
11
+ MorphoBlueAssetsData, MorphoBlueEarnData, MorphoBlueMarketData, MorphoBlueMarketInfo, MorphoBlueMarketRewards, MorphoBluePositionData,
12
12
  } from '../types';
13
13
  import { USD_QUOTE, WAD } from '../constants';
14
14
  import { calculateNetApy, getStakingApy, STAKING_ASSETS } from '../staking';
@@ -21,7 +21,39 @@ import { getViemProvider, setViemBlockNumber } from '../services/viem';
21
21
 
22
22
  const HARDCODED_USD_STABLE_PRICE = '100000000'; // $1 with 8 decimals
23
23
 
24
- export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
24
+ const getMorphoRewardIncentives = (apy: string) => [{
25
+ token: 'MORPHO',
26
+ apy,
27
+ incentiveKind: IncentiveKind.Reward,
28
+ description: 'Eligible for protocol-level MORPHO incentives.',
29
+ }];
30
+
31
+ export const addMorphoBlueRewardsToMarketInfo = (
32
+ marketInfo: MorphoBlueMarketInfo,
33
+ rewards: MorphoBlueMarketRewards,
34
+ ): MorphoBlueMarketInfo => ({
35
+ ...marketInfo,
36
+ assetsData: {
37
+ ...marketInfo.assetsData,
38
+ [marketInfo.loanToken]: {
39
+ ...marketInfo.assetsData[marketInfo.loanToken],
40
+ supplyIncentives: [
41
+ ...marketInfo.assetsData[marketInfo.loanToken].supplyIncentives.filter(({ token }) => token !== 'MORPHO'),
42
+ ...getMorphoRewardIncentives(rewards.supplyApy),
43
+ ],
44
+ borrowIncentives: [
45
+ ...marketInfo.assetsData[marketInfo.loanToken].borrowIncentives.filter(({ token }) => token !== 'MORPHO'),
46
+ ...getMorphoRewardIncentives(rewards.borrowApy),
47
+ ],
48
+ },
49
+ },
50
+ });
51
+
52
+ async function getMorphoBlueMarketDataInternal(
53
+ provider: Client,
54
+ network: NetworkNumber,
55
+ selectedMarket: MorphoBlueMarketData,
56
+ ): Promise<MorphoBlueMarketInfo> {
25
57
  const {
26
58
  loanToken, collateralToken, oracle, irm, lltv, oracleType,
27
59
  } = selectedMarket;
@@ -59,16 +91,6 @@ export async function _getMorphoBlueMarketData(provider: Client, network: Networ
59
91
  loanTokenPrice = loanTokenPriceRound[1].toString();
60
92
  }
61
93
 
62
- let morphoSupplyApy = '0';
63
- let morphoBorrowApy = '0';
64
- try {
65
- const { supplyApy: _morphoSupplyApy, borrowApy: _morphoBorrowApy } = await getRewardsForMarket(selectedMarket.marketId, network);
66
- morphoSupplyApy = _morphoSupplyApy;
67
- morphoBorrowApy = _morphoBorrowApy;
68
- } catch (e) {
69
- console.error(e);
70
- }
71
-
72
94
  const supplyRate = getSupplyRate(marketInfo.totalSupplyAssets.toString(), marketInfo.totalBorrowAssets.toString(), marketInfo.borrowRate.toString(), marketInfo.fee.toString());
73
95
  const compoundedBorrowRate = getBorrowRate(marketInfo.borrowRate.toString(), marketInfo.totalBorrowShares.toString());
74
96
  const utillization = new Dec(marketInfo.totalBorrowAssets.toString()).div(marketInfo.totalSupplyAssets.toString()).mul(100).toString();
@@ -90,18 +112,8 @@ export async function _getMorphoBlueMarketData(provider: Client, network: Networ
90
112
  totalBorrow: new Dec(marketInfo.totalBorrowAssets.toString()).div(scale).toString(),
91
113
  canBeSupplied: true,
92
114
  canBeBorrowed: true,
93
- supplyIncentives: [{
94
- token: 'MORPHO',
95
- apy: morphoSupplyApy,
96
- incentiveKind: IncentiveKind.Reward,
97
- description: 'Eligible for protocol-level MORPHO incentives.',
98
- }],
99
- borrowIncentives: [{
100
- token: 'MORPHO',
101
- apy: morphoBorrowApy,
102
- incentiveKind: IncentiveKind.Reward,
103
- description: 'Eligible for protocol-level MORPHO incentives.',
104
- }],
115
+ supplyIncentives: [],
116
+ borrowIncentives: [],
105
117
  };
106
118
 
107
119
  assetsData[wethToEth(collateralTokenInfo.symbol)] = {
@@ -138,10 +150,70 @@ export async function _getMorphoBlueMarketData(provider: Client, network: Networ
138
150
  };
139
151
  }
140
152
 
153
+ export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
154
+ const marketInfo = await getMorphoBlueMarketDataInternal(provider, network, selectedMarket);
155
+
156
+ try {
157
+ const rewards = await getRewardsForMarket(selectedMarket.marketId, network);
158
+ return addMorphoBlueRewardsToMarketInfo(marketInfo, rewards);
159
+ } catch (error) {
160
+ console.error(error);
161
+ return addMorphoBlueRewardsToMarketInfo(marketInfo, { supplyApy: '0', borrowApy: '0' });
162
+ }
163
+ }
164
+
165
+ export function _getMorphoBluePortfolioMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
166
+ return getMorphoBlueMarketDataInternal(provider, network, selectedMarket);
167
+ }
168
+
141
169
  export async function getMorphoBlueMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
142
170
  return _getMorphoBlueMarketData(getViemProvider(provider, network), network, selectedMarket);
143
171
  }
144
172
 
173
+ export function getMorphoBluePortfolioMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
174
+ return _getMorphoBluePortfolioMarketData(getViemProvider(provider, network), network, selectedMarket);
175
+ }
176
+
177
+ export const getMorphoBluePositionDataWithMarketInfo = (
178
+ data: MorphoBluePositionData,
179
+ marketInfo: MorphoBlueMarketInfo,
180
+ ): MorphoBluePositionData => ({
181
+ ...data,
182
+ ...getMorphoBlueAggregatedPositionData({
183
+ usedAssets: data.usedAssets,
184
+ assetsData: marketInfo.assetsData,
185
+ marketInfo,
186
+ }),
187
+ });
188
+
189
+ export const getMorphoEarnDataWithMarketInfo = (data: MorphoBlueEarnData, marketInfo: MorphoBlueMarketInfo): MorphoBlueEarnData => {
190
+ const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
191
+ const usedAssets: MMUsedAssets = {
192
+ [marketInfo.loanToken]: {
193
+ symbol: loanTokenInfo.symbol,
194
+ supplied: data.amount,
195
+ borrowed: '0',
196
+ isSupplied: new Dec(data.amount).gt(0),
197
+ isBorrowed: false,
198
+ collateral: false,
199
+ suppliedUsd: data.amountUsd,
200
+ borrowedUsd: '0',
201
+ },
202
+ };
203
+
204
+ return {
205
+ ...data,
206
+ apy: calculateNetApy({ usedAssets, assetsData: marketInfo.assetsData as unknown as MMAssetsData }).netApy,
207
+ };
208
+ };
209
+
210
+ export function getMorphoBlueMarketRewards(
211
+ network: NetworkNumber,
212
+ selectedMarket: MorphoBlueMarketData,
213
+ ): Promise<MorphoBlueMarketRewards> {
214
+ return getRewardsForMarket(selectedMarket.marketId, network);
215
+ }
216
+
145
217
  export const _getMorphoBlueAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoBlueMarketData): Promise<PositionBalances> => {
146
218
  let balances: PositionBalances = {
147
219
  collateral: {},
@@ -238,7 +310,7 @@ export async function getMorphoBlueAccountData(provider: EthereumProvider, netwo
238
310
  return _getMorphoBlueAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
239
311
  }
240
312
 
241
- export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<{ apy: string, amount: string, amountUsd: string }> {
313
+ export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBlueEarnData> {
242
314
  const {
243
315
  loanToken, collateralToken, oracle, irm, lltv,
244
316
  } = selectedMarket;
@@ -254,24 +326,9 @@ export async function getMorphoEarn(provider: Client, network: NetworkNumber, ac
254
326
  const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
255
327
  const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
256
328
  const loanTokenSuppliedUsd = new Dec(loanTokenSupplied).mul(loanTokenInfo.price).toString();
257
- const usedAssets: MMUsedAssets = {
258
- [marketInfo.loanToken]: {
259
- symbol: loanTokenInfo.symbol,
260
- supplied: loanTokenSupplied,
261
- borrowed: '0',
262
- isSupplied: new Dec(loanInfo.suppliedInAssets.toString()).gt(0),
263
- isBorrowed: false,
264
- collateral: false,
265
- suppliedUsd: loanTokenSuppliedUsd,
266
- borrowedUsd: '0',
267
- },
268
- };
269
-
270
- const { netApy } = calculateNetApy({ usedAssets, assetsData: marketInfo.assetsData as unknown as MMAssetsData });
271
-
272
- return {
273
- apy: netApy,
329
+ return getMorphoEarnDataWithMarketInfo({
330
+ apy: '0',
274
331
  amount: loanTokenSupplied,
275
332
  amountUsd: loanTokenSuppliedUsd,
276
- };
277
- }
333
+ }, marketInfo);
334
+ }
@@ -13,7 +13,7 @@ import {
13
13
  import { USD_QUOTE } from '../constants';
14
14
  import { calculateNetApy } from '../staking';
15
15
  import { isMainnetNetwork, wethToEth } from '../services/utils';
16
- import { getMorphoMidnightAggregatedPositionData } from '../helpers/morphoMidnightHelpers';
16
+ import { getMorphoMidnightAggregatedPositionData, getMorphoMidnightUserBorrowInfo } from '../helpers/morphoMidnightHelpers';
17
17
  import { getChainlinkAssetAddress } from '../services/priceService';
18
18
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
19
19
 
@@ -157,13 +157,40 @@ export async function _getMorphoMidnightAccountData(provider: Client, network: N
157
157
  };
158
158
  });
159
159
 
160
+ // Enrich borrower positions with the orderbook-derived rate + principal/interest split (off-chain).
161
+ // MidnightView only stores `debt` (= face value at maturity), so we default to full-debt-as-principal and
162
+ // override from the transactions API when available. Never throw here — the position must still render.
163
+ let borrowRate = '0';
164
+ let debtBase = debt; // fallback: treat the full on-chain debt as principal until fill history is known
165
+ let debtInterest = '0';
166
+ let assetsDataForApy = marketInfo.assetsData;
167
+ if (new Dec(positionInfo.debt.toString()).gt(0)) {
168
+ try {
169
+ const borrowInfo = await getMorphoMidnightUserBorrowInfo(account, marketId, marketInfo.maturity, marketInfo.loanToken);
170
+ borrowRate = borrowInfo.borrowRate;
171
+ debtBase = borrowInfo.debtBase;
172
+ debtInterest = borrowInfo.debtInterest;
173
+ usedAssets[marketInfo.loanToken].borrowRate = borrowRate;
174
+ // Reflect the real borrow cost in netApy without mutating the shared marketInfo.assetsData.
175
+ assetsDataForApy = {
176
+ ...marketInfo.assetsData,
177
+ [marketInfo.loanToken]: { ...loanTokenData, borrowRate },
178
+ };
179
+ } catch (err) {
180
+ // Orderbook API unavailable — keep the on-chain-only fallback above.
181
+ }
182
+ }
183
+
160
184
  return {
161
185
  usedAssets,
162
186
  credit,
163
187
  debt,
188
+ borrowRate,
189
+ debtBase,
190
+ debtInterest,
164
191
  maturity: marketInfo.maturity,
165
192
  isMatured: marketInfo.isMatured,
166
- ...getMorphoMidnightAggregatedPositionData({ usedAssets, assetsData: marketInfo.assetsData, marketInfo }),
193
+ ...getMorphoMidnightAggregatedPositionData({ usedAssets, assetsData: assetsDataForApy, marketInfo }),
167
194
  };
168
195
  }
169
196
 
@@ -12,7 +12,7 @@ import {
12
12
  MorphoMidnightMarkets,
13
13
  SparkMarkets,
14
14
  } from '../markets';
15
- import { _getMorphoBlueAccountData, _getMorphoBlueMarketData, getMorphoEarn } from '../morphoBlue';
15
+ import { _getMorphoBlueAccountData, _getMorphoBluePortfolioMarketData, getMorphoEarn } from '../morphoBlue';
16
16
  import { _getMorphoMidnightAccountData, _getMorphoMidnightMarketData, getMorphoMidnightEarn } from '../morphoMidnight';
17
17
  import {
18
18
  AaveV2MarketData,
@@ -54,6 +54,7 @@ import { fetchSparkAirdropRewards, fetchSparkRewards } from '../claiming/spark';
54
54
  import { getKingRewards } from '../claiming/king';
55
55
  import { fetchEthenaAirdropRewards } from '../claiming/ethena';
56
56
  import { _getAaveV4AccountData, _getAaveV4SpokeData } from '../aaveV4';
57
+ import { getUniswapRewards } from '../claiming/uniswap';
57
58
 
58
59
  export async function getPortfolioData(provider: EthereumProvider, network: NetworkNumber, defaultProvider: EthereumProvider, addresses: EthAddress[], isSim = false): Promise<{
59
60
  positions: PortfolioPositionsData;
@@ -78,7 +79,8 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
78
79
  const liquityV2MarketsStaking = [NetworkNumber.Eth].includes(network) ? Object.values(LiquityV2Markets(network)).filter(market => !market.isLegacy) : [];
79
80
  const aaveV4Spokes = Object.values(AaveV4Spokes(network)).filter((market) => market.chainIds.includes(network));
80
81
 
81
- const args: [NetworkNumber, any?] = [network, { batch: { multicall: { batchSize: isSim ? 500_000 : 2_500_000 } } }];
82
+
83
+ const args: [NetworkNumber, any?] = [network, { batch: { multicall: { batchSize: isSim ? 2_000 : 2_500_000 } } }];
82
84
  const client = getViemProvider(provider, ...args);
83
85
  const defaultClient = getViemProvider(defaultProvider, ...args);
84
86
 
@@ -170,7 +172,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
170
172
  await Promise.allSettled([
171
173
  // === MARKET DATA (needs to be fetched first) ===
172
174
  ...morphoMarkets.map(async (market) => {
173
- const marketData = await _getMorphoBlueMarketData(client, network, market);
175
+ const marketData = await _getMorphoBluePortfolioMarketData(client, network, market);
174
176
  morphoMarketsData[market.value] = marketData;
175
177
  }),
176
178
  ...morphoMidnightMarkets.map(async (market) => {
@@ -322,6 +324,33 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
322
324
  }
323
325
  }
324
326
  })(),
327
+ // Batch UNI rewards
328
+ (async () => {
329
+ try {
330
+ if (!isMainnet) {
331
+ for (const address of addresses) {
332
+ rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
333
+ }
334
+ return;
335
+ }
336
+ const uniswapRewards = await getUniswapRewards(client, network, addresses);
337
+ for (const address of addresses) {
338
+ const lowerAddress = address.toLowerCase() as EthAddress;
339
+ rewardsData[lowerAddress].uniswap = {
340
+ error: '',
341
+ data: uniswapRewards[lowerAddress] || [],
342
+ };
343
+ }
344
+ } catch (error) {
345
+ console.error('Error fetching Uniswap rewards data in batch:', error);
346
+ for (const address of addresses) {
347
+ rewardsData[address.toLowerCase() as EthAddress].uniswap = {
348
+ error: 'Error fetching Uniswap rewards data in batch',
349
+ data: null,
350
+ };
351
+ }
352
+ }
353
+ })(),
325
354
  ...sparkMarkets.map((market) => addresses.map(async address => {
326
355
  try {
327
356
  if (!isMainnet) {
@@ -8,7 +8,7 @@ export const SUMMER_VAULT_USDC_MAINNET_LR: SummerVault = {
8
8
  asset: 'USDC',
9
9
  network: NetworkNumber.Eth,
10
10
  deploymentBlock: 21795049,
11
- isLegacy: false,
11
+ isLegacy: true,
12
12
  };
13
13
 
14
14
  export const SUMMER_VAULT_USDC_MAINNET_HR: SummerVault = {
@@ -18,7 +18,7 @@ export const SUMMER_VAULT_USDC_MAINNET_HR: SummerVault = {
18
18
  asset: 'USDC',
19
19
  network: NetworkNumber.Eth,
20
20
  deploymentBlock: 22488041,
21
- isLegacy: false,
21
+ isLegacy: true,
22
22
  };
23
23
 
24
24
  export const SUMMER_VAULT_USDT_MAINNET_LR: SummerVault = {
@@ -28,7 +28,7 @@ export const SUMMER_VAULT_USDT_MAINNET_LR: SummerVault = {
28
28
  asset: 'USDT',
29
29
  network: NetworkNumber.Eth,
30
30
  deploymentBlock: 21795276,
31
- isLegacy: false,
31
+ isLegacy: true,
32
32
  };
33
33
 
34
34
  export const SUMMER_VAULT_ETH_MAINNET_LR: SummerVault = {
@@ -38,7 +38,7 @@ export const SUMMER_VAULT_ETH_MAINNET_LR: SummerVault = {
38
38
  asset: 'WETH',
39
39
  network: NetworkNumber.Eth,
40
40
  deploymentBlock: 21795390,
41
- isLegacy: false,
41
+ isLegacy: true,
42
42
  };
43
43
 
44
44
  export const SUMMER_VAULT_ETH_MAINNET_HR: SummerVault = {
@@ -48,7 +48,7 @@ export const SUMMER_VAULT_ETH_MAINNET_HR: SummerVault = {
48
48
  asset: 'WETH',
49
49
  network: NetworkNumber.Eth,
50
50
  deploymentBlock: 22291252,
51
- isLegacy: false,
51
+ isLegacy: true,
52
52
  };
53
53
 
54
54
  export const SUMMER_VAULT_USDC_ARBITRUM_LR: SummerVault = {
@@ -58,7 +58,7 @@ export const SUMMER_VAULT_USDC_ARBITRUM_LR: SummerVault = {
58
58
  asset: 'USDC',
59
59
  network: NetworkNumber.Arb,
60
60
  deploymentBlock: 404339289,
61
- isLegacy: false,
61
+ isLegacy: true,
62
62
  };
63
63
 
64
64
  export const SUMMER_VAULT_USDT_ARBITRUM_LR: SummerVault = {
@@ -68,7 +68,7 @@ export const SUMMER_VAULT_USDT_ARBITRUM_LR: SummerVault = {
68
68
  asset: 'USDT',
69
69
  network: NetworkNumber.Arb,
70
70
  deploymentBlock: 303594065,
71
- isLegacy: false,
71
+ isLegacy: true,
72
72
  };
73
73
 
74
74
  export const SUMMER_VAULT_USDC_BASE_LR: SummerVault = {
@@ -78,7 +78,7 @@ export const SUMMER_VAULT_USDC_BASE_LR: SummerVault = {
78
78
  asset: 'USDC',
79
79
  network: NetworkNumber.Base,
80
80
  deploymentBlock: 303594065,
81
- isLegacy: false,
81
+ isLegacy: true,
82
82
  };
83
83
 
84
84
  export const SUMMER_VAULT_EURC_BASE_LR: SummerVault = {
@@ -88,7 +88,7 @@ export const SUMMER_VAULT_EURC_BASE_LR: SummerVault = {
88
88
  asset: 'EURC',
89
89
  network: NetworkNumber.Base,
90
90
  deploymentBlock: 27544064,
91
- isLegacy: false,
91
+ isLegacy: true,
92
92
  };
93
93
 
94
94
  export const SUMMER_VAULT_ETH_BASE_LR: SummerVault = {
@@ -98,7 +98,7 @@ export const SUMMER_VAULT_ETH_BASE_LR: SummerVault = {
98
98
  asset: 'WETH',
99
99
  network: NetworkNumber.Base,
100
100
  deploymentBlock: 29066887,
101
- isLegacy: false,
101
+ isLegacy: true,
102
102
  };
103
103
 
104
104
  export const SUMMER_VAULTS: Record<SummerVaultType, SummerVault> = {
@@ -66,6 +66,7 @@ export const STAKING_ASSETS = [
66
66
  'PT sUSDe Nov', 'PT USDe Nov', 'PT USDe Jan', 'PT sUSDe Jan', 'wrsETH', 'wstETH', 'syrupUSDT', 'syrupUSDC', 'wstUSR',
67
67
  'PT sUSDe Feb', 'PT USDe Feb', 'PT sUSDe Apr', 'PT USDe Apr', 'PT sUSDe May', 'PT USDe May', 'PT srUSDe Apr', 'GHO',
68
68
  'PT sUSDe June', 'PT USDe June', 'PT srUSDe Jun', 'PT srUSDe Oct', 'PT USDG May', 'PT sUSDS Nov', 'PT sUSDe Oct', 'PT USDG Sep',
69
+ 'syrupUSDG',
69
70
  ];
70
71
 
71
72
  export const getStakingApy = memoize(async (asset: string, network: number = NetworkNumber.Eth) => {
@@ -97,6 +98,7 @@ export const getStakingApy = memoize(async (asset: string, network: number = Net
97
98
  if (asset === 'PT sUSDe Jan') return await getApyFromDfsApi('PT sUSDe Jan', network);
98
99
  if (asset === 'syrupUSDT') return await getApyFromDfsApi('syrupUSDT');
99
100
  if (asset === 'syrupUSDC') return await getApyFromDfsApi('syrupUSDC');
101
+ if (asset === 'syrupUSDG') return await getApyFromDfsApi('syrupUSDG');
100
102
  if (asset === 'wstUSR') return await getApyFromDfsApi('wstUSR');
101
103
  if (asset === 'PT sUSDe Feb') return await getApyFromDfsApi('PT sUSDe Feb', network);
102
104
  if (asset === 'PT USDe Feb') return await getApyFromDfsApi('PT USDe Feb', network);
@@ -21,6 +21,7 @@ export enum AaveV4SpokesType {
21
21
  AaveV4LombardBtcSpoke = 'aave_v4_lombard_btc_spoke',
22
22
  AaveV4MainSpoke = 'aave_v4_main_spoke',
23
23
  AaveV4USDGPendleSpoke = 'aave_v4_usdg_pendle_spoke',
24
+ AaveV4USDGMapleSpoke = 'aave_v4_usdg_maple_spoke',
24
25
  }
25
26
 
26
27
  export interface AaveV4HubInfo {
@@ -15,6 +15,8 @@ export enum ClaimType {
15
15
  SPARK_AIRDROP = 'SPARK_AIRDROP',
16
16
  /** Spark Airdrop */
17
17
  SPARK_WST_ETH_REWARDS = 'SPARK_WST_ETH_REWARDS', // TODO: This will be removed once we fully refactor spark rewards
18
+ /** UNI Airdrop */
19
+ UNI_REWARDS = 'UNI_REWARDS',
18
20
 
19
21
  ETHENA_AIRDROP = 'ETHENA_AIRDROP',
20
22
  }
@@ -88,6 +90,15 @@ export type SparkWstEthRewardsClaimableToken = _ClaimableTokenPartial & { claimT
88
90
 
89
91
  export type EthenaAirdropClaimableToken = _ClaimableTokenPartial & { claimType: ClaimType.ETHENA_AIRDROP };
90
92
 
93
+ export type UniswapAirdropClaimableToken = _ClaimableTokenPartial & {
94
+ claimType: ClaimType.UNI_REWARDS,
95
+ additionalClaimFields: {
96
+ index: number;
97
+ isClaimed: boolean;
98
+ proof: string[];
99
+ };
100
+ };
101
+
91
102
  export type ClaimableToken =
92
103
  AaveRewardsClaimableToken
93
104
  | AaveMeritRewardsClaimableToken
@@ -235,6 +235,17 @@ export interface MorphoBluePositionData {
235
235
  exposure: string,
236
236
  }
237
237
 
238
+ export interface MorphoBlueEarnData {
239
+ apy: string,
240
+ amount: string,
241
+ amountUsd: string,
242
+ }
243
+
244
+ export interface MorphoBlueMarketRewards {
245
+ supplyApy: string,
246
+ borrowApy: string,
247
+ }
248
+
238
249
  export interface MorphoBlueVault {
239
250
  address: string,
240
251
  }
@@ -99,6 +99,12 @@ export interface MorphoMidnightPositionData extends MorphoMidnightAggregatedPosi
99
99
  usedAssets: MMUsedAssets,
100
100
  credit: string, // lender credit units, face value at maturity (with interest); 0 for borrowers
101
101
  debt: string, // borrower debt, face value at maturity (with interest); 0 for lenders
102
+ // Borrow rate + base/interest split are orderbook-derived off-chain (from the Midnight transactions API):
103
+ // MidnightView only stores `debt` (= face value at maturity), so principal-vs-interest and the effective
104
+ // rate are computed from the fill history. Default to '0'/`debt`/'0' for lenders or when the API is unavailable.
105
+ borrowRate: string, // weighted-average borrow APY as a percent
106
+ debtBase: string, // base borrowed (principal), loan-token units
107
+ debtInterest: string, // debt − debtBase (fixed interest owed at maturity), loan-token units
102
108
  maturity: number,
103
109
  isMatured: boolean,
104
110
  }