@defisaver/positions-sdk 2.1.49-aave-v4-dev-1-dev → 2.1.49-aave-v4-dev-2

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 (116) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/helpers/aaveV4Helpers/index.d.ts +4 -0
  5. package/cjs/helpers/aaveV4Helpers/index.js +54 -2
  6. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  7. package/cjs/savings/morphoVaults/index.js +17 -17
  8. package/esm/helpers/aaveV4Helpers/index.d.ts +4 -0
  9. package/esm/helpers/aaveV4Helpers/index.js +53 -2
  10. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  11. package/esm/savings/morphoVaults/index.js +17 -17
  12. package/package.json +48 -48
  13. package/src/aaveV2/index.ts +240 -240
  14. package/src/aaveV3/index.ts +635 -635
  15. package/src/aaveV3/merit.ts +97 -97
  16. package/src/aaveV3/merkl.ts +74 -74
  17. package/src/aaveV4/index.ts +168 -168
  18. package/src/claiming/aaveV3.ts +154 -154
  19. package/src/claiming/compV3.ts +22 -22
  20. package/src/claiming/ethena.ts +61 -61
  21. package/src/claiming/index.ts +12 -12
  22. package/src/claiming/king.ts +66 -66
  23. package/src/claiming/morphoBlue.ts +118 -118
  24. package/src/claiming/spark.ts +225 -225
  25. package/src/compoundV2/index.ts +244 -244
  26. package/src/compoundV3/index.ts +274 -274
  27. package/src/config/contracts.ts +1328 -1328
  28. package/src/constants/index.ts +10 -10
  29. package/src/contracts.ts +173 -173
  30. package/src/curveUsd/index.ts +254 -254
  31. package/src/eulerV2/index.ts +324 -324
  32. package/src/exchange/index.ts +25 -25
  33. package/src/fluid/index.ts +1800 -1800
  34. package/src/helpers/aaveHelpers/index.ts +191 -191
  35. package/src/helpers/aaveV4Helpers/index.ts +120 -68
  36. package/src/helpers/compoundHelpers/index.ts +283 -283
  37. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  38. package/src/helpers/eulerHelpers/index.ts +222 -222
  39. package/src/helpers/fluidHelpers/index.ts +326 -326
  40. package/src/helpers/index.ts +11 -11
  41. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  42. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  43. package/src/helpers/makerHelpers/index.ts +52 -52
  44. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  45. package/src/helpers/sparkHelpers/index.ts +158 -158
  46. package/src/index.ts +51 -51
  47. package/src/liquity/index.ts +159 -159
  48. package/src/liquityV2/index.ts +703 -703
  49. package/src/llamaLend/index.ts +305 -305
  50. package/src/maker/index.ts +223 -223
  51. package/src/markets/aave/index.ts +118 -118
  52. package/src/markets/aave/marketAssets.ts +54 -54
  53. package/src/markets/aaveV4/index.ts +18 -18
  54. package/src/markets/compound/index.ts +243 -243
  55. package/src/markets/compound/marketsAssets.ts +97 -97
  56. package/src/markets/curveUsd/index.ts +69 -69
  57. package/src/markets/euler/index.ts +26 -26
  58. package/src/markets/fluid/index.ts +2900 -2900
  59. package/src/markets/index.ts +25 -25
  60. package/src/markets/liquityV2/index.ts +102 -102
  61. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  62. package/src/markets/llamaLend/index.ts +235 -235
  63. package/src/markets/morphoBlue/index.ts +971 -971
  64. package/src/markets/spark/index.ts +29 -29
  65. package/src/markets/spark/marketAssets.ts +12 -12
  66. package/src/moneymarket/moneymarketCommonService.ts +85 -85
  67. package/src/morphoBlue/index.ts +274 -274
  68. package/src/portfolio/index.ts +618 -618
  69. package/src/savings/index.ts +95 -95
  70. package/src/savings/makerDsr/index.ts +53 -53
  71. package/src/savings/makerDsr/options.ts +9 -9
  72. package/src/savings/morphoVaults/index.ts +80 -80
  73. package/src/savings/morphoVaults/options.ts +193 -193
  74. package/src/savings/skyOptions/index.ts +95 -95
  75. package/src/savings/skyOptions/options.ts +10 -10
  76. package/src/savings/sparkSavingsVaults/index.ts +60 -60
  77. package/src/savings/sparkSavingsVaults/options.ts +35 -35
  78. package/src/savings/yearnV3Vaults/index.ts +61 -61
  79. package/src/savings/yearnV3Vaults/options.ts +55 -55
  80. package/src/savings/yearnVaults/index.ts +73 -73
  81. package/src/savings/yearnVaults/options.ts +32 -32
  82. package/src/services/priceService.ts +278 -278
  83. package/src/services/utils.ts +115 -115
  84. package/src/services/viem.ts +34 -34
  85. package/src/setup.ts +8 -8
  86. package/src/spark/index.ts +459 -459
  87. package/src/staking/eligibility.ts +53 -53
  88. package/src/staking/index.ts +1 -1
  89. package/src/staking/staking.ts +192 -192
  90. package/src/types/aave.ts +198 -198
  91. package/src/types/aaveV4.ts +142 -142
  92. package/src/types/claiming.ts +114 -114
  93. package/src/types/common.ts +107 -107
  94. package/src/types/compound.ts +144 -144
  95. package/src/types/curveUsd.ts +123 -123
  96. package/src/types/euler.ts +175 -175
  97. package/src/types/fluid.ts +483 -483
  98. package/src/types/index.ts +15 -15
  99. package/src/types/liquity.ts +30 -30
  100. package/src/types/liquityV2.ts +126 -126
  101. package/src/types/llamaLend.ts +159 -159
  102. package/src/types/maker.ts +63 -63
  103. package/src/types/merit.ts +1 -1
  104. package/src/types/merkl.ts +70 -70
  105. package/src/types/morphoBlue.ts +200 -200
  106. package/src/types/portfolio.ts +64 -64
  107. package/src/types/savings/index.ts +23 -23
  108. package/src/types/savings/makerDsr.ts +13 -13
  109. package/src/types/savings/morphoVaults.ts +32 -32
  110. package/src/types/savings/sky.ts +14 -14
  111. package/src/types/savings/sparkSavingsVaults.ts +15 -15
  112. package/src/types/savings/yearnV3Vaults.ts +17 -17
  113. package/src/types/savings/yearnVaults.ts +14 -14
  114. package/src/types/spark.ts +134 -134
  115. package/src/umbrella/index.ts +69 -69
  116. package/src/umbrella/umbrellaUtils.ts +29 -29
@@ -1,169 +1,169 @@
1
- import { Client } from 'viem';
2
- import Dec from 'decimal.js';
3
- import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
4
- import { getViemProvider } from '../services/viem';
5
- import {
6
- AaveV4AccountData,
7
- AaveV4HubAssetOnChainData,
8
- AaveV4HubOnChainData,
9
- AaveV4ReserveAssetData, AaveV4ReserveAssetOnChain, AaveV4SpokeData, AaveV4SpokeInfo,
10
- AaveV4UsedReserveAssets,
11
- } from '../types';
12
- import {
13
- EthAddress, EthereumProvider, IncentiveData, IncentiveKind, NetworkNumber,
14
- } from '../types/common';
15
- import { AaveV4ViewContractViem } from '../contracts';
16
- import { getStakingApy, STAKING_ASSETS } from '../staking';
17
- import { wethToEth } from '../services/utils';
18
- import { aaveV4GetAggregatedPositionData } from '../helpers/aaveV4Helpers';
19
-
20
- const fetchHubData = async (viewContract: ReturnType<typeof AaveV4ViewContractViem>, hubAddress: EthAddress): Promise<AaveV4HubOnChainData> => {
21
- const hubData = await viewContract.read.getHubAllAssetsData([hubAddress]);
22
- return {
23
- assets: hubData.reduce((acc: Record<number, AaveV4HubAssetOnChainData>, assetOnChainData) => {
24
- acc[assetOnChainData.assetId] = {
25
- assetId: assetOnChainData.assetId,
26
- drawnRate: assetOnChainData.drawnRate,
27
- };
28
- return acc;
29
- }, {}),
30
- };
31
- };
32
-
33
- const formatReserveAsset = async (reserveAsset: AaveV4ReserveAssetOnChain, hubAsset: AaveV4HubAssetOnChainData, reserveId: number, oracleDecimals: number, network: NetworkNumber): Promise<AaveV4ReserveAssetData> => {
34
- const assetInfo = getAssetInfoByAddress(reserveAsset.underlying, network);
35
- const symbol = wethToEth(assetInfo.symbol);
36
-
37
- const isStakingAsset = STAKING_ASSETS.includes(symbol);
38
- const supplyIncentives: IncentiveData[] = [];
39
- const borrowIncentives: IncentiveData[] = [];
40
-
41
- if (isStakingAsset) {
42
- const yieldApy = await getStakingApy(symbol, network as NetworkNumber);
43
- supplyIncentives.push({
44
- apy: yieldApy,
45
- token: symbol,
46
- incentiveKind: IncentiveKind.Staking,
47
- description: `Native ${symbol} yield.`,
48
- });
49
- if (reserveAsset.borrowable) {
50
- // when borrowing assets whose value increases over time
51
- borrowIncentives.push({
52
- apy: new Dec(yieldApy).mul(-1).toString(),
53
- token: symbol,
54
- incentiveKind: IncentiveKind.Reward,
55
- description: `Due to the native yield of ${symbol}, the value of the debt would increase over time.`,
56
- });
57
- }
58
- }
59
-
60
- return ({
61
- symbol,
62
- underlying: reserveAsset.underlying,
63
- hub: reserveAsset.hub,
64
- assetId: reserveAsset.assetId,
65
- reserveId,
66
- paused: reserveAsset.paused,
67
- frozen: reserveAsset.frozen,
68
- borrowable: reserveAsset.borrowable,
69
- collateralRisk: new Dec(reserveAsset.collateralRisk).div(10000).toNumber(),
70
- collateralFactor: new Dec(reserveAsset.collateralFactor).div(10000).toNumber(),
71
- liquidationFee: new Dec(reserveAsset.liquidationFee).div(10000).toNumber(),
72
- price: new Dec(reserveAsset.price).div(new Dec(10).pow(oracleDecimals)).toString(),
73
- totalSupplied: assetAmountInEth(reserveAsset.totalSupplied.toString(), symbol),
74
- totalDrawn: assetAmountInEth(reserveAsset.totalDrawn.toString(), symbol),
75
- totalPremium: assetAmountInEth(reserveAsset.totalPremium.toString(), symbol),
76
- totalDebt: assetAmountInEth(reserveAsset.totalDebt.toString(), symbol),
77
- supplyCap: assetAmountInEth(reserveAsset.supplyCap.toString(), symbol),
78
- borrowCap: assetAmountInEth(reserveAsset.borrowCap.toString(), symbol),
79
- spokeActive: reserveAsset.spokeActive,
80
- spokePaused: reserveAsset.spokePaused,
81
- drawnRate: new Dec(hubAsset.drawnRate).div(new Dec(10).pow(27)).toString(),
82
- supplyRate: '0', // To be implemented
83
- supplyIncentives,
84
- borrowIncentives,
85
- canBeBorrowed: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused && !reserveAsset.frozen,
86
- canBeSupplied: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused && !reserveAsset.frozen,
87
- canBeWithdrawn: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused,
88
- canBePayBacked: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused,
89
- utilization: new Dec(reserveAsset.totalDrawn.toString()).times(100).div(new Dec(reserveAsset.totalSupplied.toString())).toString(),
90
- });
91
- };
92
-
93
- export async function _getAaveV4SpokeData(provider: Client, network: NetworkNumber, market: AaveV4SpokeInfo, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4SpokeData> {
94
- const viewContract = AaveV4ViewContractViem(provider, network, blockNumber);
95
-
96
- const hubsData: Record<EthAddress, AaveV4HubOnChainData> = {};
97
- const [spokeData] = await Promise.all([
98
- viewContract.read.getSpokeDataFull([market.address]),
99
- ...market.hubs.map(async (hubAddress) => {
100
- hubsData[hubAddress] = await fetchHubData(viewContract, hubAddress);
101
- }),
102
- ]);
103
-
104
- const reserveAssetsArray = await Promise.all(spokeData[1].map(async (reserveAssetOnChain: AaveV4ReserveAssetOnChain, index: number) => formatReserveAsset(reserveAssetOnChain, hubsData[reserveAssetOnChain.hub].assets[reserveAssetOnChain.assetId], index, +spokeData[0].oracleDecimals.toString(), network)));
105
-
106
- return {
107
- assetsData: reserveAssetsArray.reduce((acc: Record<string, AaveV4ReserveAssetData>, reserveAsset: AaveV4ReserveAssetData) => {
108
- acc[`${reserveAsset.symbol}-${reserveAsset.reserveId}`] = reserveAsset;
109
- return acc;
110
- }, {}),
111
- oracle: spokeData[0].oracle,
112
- oracleDecimals: +spokeData[0].oracleDecimals.toString(),
113
- address: market.address,
114
- };
115
- }
116
-
117
- export async function getAaveV4SpokeData(provider: EthereumProvider, network: NetworkNumber, spoke: AaveV4SpokeInfo, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4SpokeData> {
118
- return _getAaveV4SpokeData(getViemProvider(provider, network), network, spoke, blockNumber);
119
- }
120
-
121
- export async function _getAaveV4AccountData(provider: Client, network: NetworkNumber, spokeData: AaveV4SpokeData, address: EthAddress, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4AccountData> {
122
- const viewContract = AaveV4ViewContractViem(provider, network, blockNumber);
123
-
124
- const loanData = await viewContract.read.getLoanData([spokeData.address, address]);
125
-
126
- const healthFactor = new Dec(loanData.healthFactor).div(1e18).toString();
127
- const usedAssets = loanData.reserves.reduce((acc: AaveV4UsedReserveAssets, usedReserveAsset) => {
128
- const identifier = `${wethToEth(getAssetInfoByAddress(usedReserveAsset.underlying, network).symbol)}-${+usedReserveAsset.reserveId.toString()}`;
129
- const reserveData = spokeData.assetsData[identifier];
130
- const price = reserveData.price;
131
- const supplied = assetAmountInEth(usedReserveAsset.supplied.toString(), reserveData.symbol);
132
- const drawn = assetAmountInEth(usedReserveAsset.drawn.toString(), reserveData.symbol);
133
- const premium = assetAmountInEth(usedReserveAsset.premium.toString(), reserveData.symbol);
134
- const borrowed = assetAmountInEth(usedReserveAsset.totalDebt.toString(), reserveData.symbol);
135
- acc[identifier] = {
136
- symbol: reserveData.symbol,
137
- assetId: reserveData.assetId,
138
- reserveId: +usedReserveAsset.reserveId.toString(),
139
- supplied,
140
- suppliedUsd: new Dec(supplied).mul(price).toString(),
141
- drawn,
142
- drawnUsd: new Dec(drawn).mul(price).toString(),
143
- premium,
144
- premiumUsd: new Dec(premium).mul(price).toString(),
145
- borrowed,
146
- borrowedUsd: new Dec(borrowed).mul(price).toString(),
147
- isSupplied: !new Dec(supplied).eq(0),
148
- isBorrowed: usedReserveAsset.isBorrowing,
149
- collateral: usedReserveAsset.isUsingAsCollateral,
150
- collateralFactor: new Dec(usedReserveAsset.collateralFactor).div(10000).toNumber(),
151
- };
152
- return acc;
153
- }, {});
154
-
155
- return {
156
- usedAssets,
157
- healthFactor,
158
- ...aaveV4GetAggregatedPositionData({
159
- usedAssets,
160
- assetsData: spokeData.assetsData,
161
- network,
162
- useUserCollateralFactor: true,
163
- }),
164
- };
165
- }
166
-
167
- export async function getAaveV4AccountData(provider: EthereumProvider, network: NetworkNumber, marketData: AaveV4SpokeData, address: EthAddress, blockNumber: 'latest' | number = 'latest'): Promise<any> {
168
- return _getAaveV4AccountData(getViemProvider(provider, network), network, marketData, address, blockNumber);
1
+ import { Client } from 'viem';
2
+ import Dec from 'decimal.js';
3
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
4
+ import { getViemProvider } from '../services/viem';
5
+ import {
6
+ AaveV4AccountData,
7
+ AaveV4HubAssetOnChainData,
8
+ AaveV4HubOnChainData,
9
+ AaveV4ReserveAssetData, AaveV4ReserveAssetOnChain, AaveV4SpokeData, AaveV4SpokeInfo,
10
+ AaveV4UsedReserveAssets,
11
+ } from '../types';
12
+ import {
13
+ EthAddress, EthereumProvider, IncentiveData, IncentiveKind, NetworkNumber,
14
+ } from '../types/common';
15
+ import { AaveV4ViewContractViem } from '../contracts';
16
+ import { getStakingApy, STAKING_ASSETS } from '../staking';
17
+ import { wethToEth } from '../services/utils';
18
+ import { aaveV4GetAggregatedPositionData } from '../helpers/aaveV4Helpers';
19
+
20
+ const fetchHubData = async (viewContract: ReturnType<typeof AaveV4ViewContractViem>, hubAddress: EthAddress): Promise<AaveV4HubOnChainData> => {
21
+ const hubData = await viewContract.read.getHubAllAssetsData([hubAddress]);
22
+ return {
23
+ assets: hubData.reduce((acc: Record<number, AaveV4HubAssetOnChainData>, assetOnChainData) => {
24
+ acc[assetOnChainData.assetId] = {
25
+ assetId: assetOnChainData.assetId,
26
+ drawnRate: assetOnChainData.drawnRate,
27
+ };
28
+ return acc;
29
+ }, {}),
30
+ };
31
+ };
32
+
33
+ const formatReserveAsset = async (reserveAsset: AaveV4ReserveAssetOnChain, hubAsset: AaveV4HubAssetOnChainData, reserveId: number, oracleDecimals: number, network: NetworkNumber): Promise<AaveV4ReserveAssetData> => {
34
+ const assetInfo = getAssetInfoByAddress(reserveAsset.underlying, network);
35
+ const symbol = wethToEth(assetInfo.symbol);
36
+
37
+ const isStakingAsset = STAKING_ASSETS.includes(symbol);
38
+ const supplyIncentives: IncentiveData[] = [];
39
+ const borrowIncentives: IncentiveData[] = [];
40
+
41
+ if (isStakingAsset) {
42
+ const yieldApy = await getStakingApy(symbol, network as NetworkNumber);
43
+ supplyIncentives.push({
44
+ apy: yieldApy,
45
+ token: symbol,
46
+ incentiveKind: IncentiveKind.Staking,
47
+ description: `Native ${symbol} yield.`,
48
+ });
49
+ if (reserveAsset.borrowable) {
50
+ // when borrowing assets whose value increases over time
51
+ borrowIncentives.push({
52
+ apy: new Dec(yieldApy).mul(-1).toString(),
53
+ token: symbol,
54
+ incentiveKind: IncentiveKind.Reward,
55
+ description: `Due to the native yield of ${symbol}, the value of the debt would increase over time.`,
56
+ });
57
+ }
58
+ }
59
+
60
+ return ({
61
+ symbol,
62
+ underlying: reserveAsset.underlying,
63
+ hub: reserveAsset.hub,
64
+ assetId: reserveAsset.assetId,
65
+ reserveId,
66
+ paused: reserveAsset.paused,
67
+ frozen: reserveAsset.frozen,
68
+ borrowable: reserveAsset.borrowable,
69
+ collateralRisk: new Dec(reserveAsset.collateralRisk).div(10000).toNumber(),
70
+ collateralFactor: new Dec(reserveAsset.collateralFactor).div(10000).toNumber(),
71
+ liquidationFee: new Dec(reserveAsset.liquidationFee).div(10000).toNumber(),
72
+ price: new Dec(reserveAsset.price).div(new Dec(10).pow(oracleDecimals)).toString(),
73
+ totalSupplied: assetAmountInEth(reserveAsset.totalSupplied.toString(), symbol),
74
+ totalDrawn: assetAmountInEth(reserveAsset.totalDrawn.toString(), symbol),
75
+ totalPremium: assetAmountInEth(reserveAsset.totalPremium.toString(), symbol),
76
+ totalDebt: assetAmountInEth(reserveAsset.totalDebt.toString(), symbol),
77
+ supplyCap: assetAmountInEth(reserveAsset.supplyCap.toString(), symbol),
78
+ borrowCap: assetAmountInEth(reserveAsset.borrowCap.toString(), symbol),
79
+ spokeActive: reserveAsset.spokeActive,
80
+ spokePaused: reserveAsset.spokePaused,
81
+ drawnRate: new Dec(hubAsset.drawnRate).div(new Dec(10).pow(27)).toString(),
82
+ supplyRate: '0', // To be implemented
83
+ supplyIncentives,
84
+ borrowIncentives,
85
+ canBeBorrowed: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused && !reserveAsset.frozen,
86
+ canBeSupplied: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused && !reserveAsset.frozen,
87
+ canBeWithdrawn: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused,
88
+ canBePayBacked: reserveAsset.spokeActive && !reserveAsset.spokePaused && !reserveAsset.paused,
89
+ utilization: new Dec(reserveAsset.totalDrawn.toString()).times(100).div(new Dec(reserveAsset.totalSupplied.toString())).toString(),
90
+ });
91
+ };
92
+
93
+ export async function _getAaveV4SpokeData(provider: Client, network: NetworkNumber, market: AaveV4SpokeInfo, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4SpokeData> {
94
+ const viewContract = AaveV4ViewContractViem(provider, network, blockNumber);
95
+
96
+ const hubsData: Record<EthAddress, AaveV4HubOnChainData> = {};
97
+ const [spokeData] = await Promise.all([
98
+ viewContract.read.getSpokeDataFull([market.address]),
99
+ ...market.hubs.map(async (hubAddress) => {
100
+ hubsData[hubAddress] = await fetchHubData(viewContract, hubAddress);
101
+ }),
102
+ ]);
103
+
104
+ const reserveAssetsArray = await Promise.all(spokeData[1].map(async (reserveAssetOnChain: AaveV4ReserveAssetOnChain, index: number) => formatReserveAsset(reserveAssetOnChain, hubsData[reserveAssetOnChain.hub].assets[reserveAssetOnChain.assetId], index, +spokeData[0].oracleDecimals.toString(), network)));
105
+
106
+ return {
107
+ assetsData: reserveAssetsArray.reduce((acc: Record<string, AaveV4ReserveAssetData>, reserveAsset: AaveV4ReserveAssetData) => {
108
+ acc[`${reserveAsset.symbol}-${reserveAsset.reserveId}`] = reserveAsset;
109
+ return acc;
110
+ }, {}),
111
+ oracle: spokeData[0].oracle,
112
+ oracleDecimals: +spokeData[0].oracleDecimals.toString(),
113
+ address: market.address,
114
+ };
115
+ }
116
+
117
+ export async function getAaveV4SpokeData(provider: EthereumProvider, network: NetworkNumber, spoke: AaveV4SpokeInfo, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4SpokeData> {
118
+ return _getAaveV4SpokeData(getViemProvider(provider, network), network, spoke, blockNumber);
119
+ }
120
+
121
+ export async function _getAaveV4AccountData(provider: Client, network: NetworkNumber, spokeData: AaveV4SpokeData, address: EthAddress, blockNumber: 'latest' | number = 'latest'): Promise<AaveV4AccountData> {
122
+ const viewContract = AaveV4ViewContractViem(provider, network, blockNumber);
123
+
124
+ const loanData = await viewContract.read.getLoanData([spokeData.address, address]);
125
+
126
+ const healthFactor = new Dec(loanData.healthFactor).div(1e18).toString();
127
+ const usedAssets = loanData.reserves.reduce((acc: AaveV4UsedReserveAssets, usedReserveAsset) => {
128
+ const identifier = `${wethToEth(getAssetInfoByAddress(usedReserveAsset.underlying, network).symbol)}-${+usedReserveAsset.reserveId.toString()}`;
129
+ const reserveData = spokeData.assetsData[identifier];
130
+ const price = reserveData.price;
131
+ const supplied = assetAmountInEth(usedReserveAsset.supplied.toString(), reserveData.symbol);
132
+ const drawn = assetAmountInEth(usedReserveAsset.drawn.toString(), reserveData.symbol);
133
+ const premium = assetAmountInEth(usedReserveAsset.premium.toString(), reserveData.symbol);
134
+ const borrowed = assetAmountInEth(usedReserveAsset.totalDebt.toString(), reserveData.symbol);
135
+ acc[identifier] = {
136
+ symbol: reserveData.symbol,
137
+ assetId: reserveData.assetId,
138
+ reserveId: +usedReserveAsset.reserveId.toString(),
139
+ supplied,
140
+ suppliedUsd: new Dec(supplied).mul(price).toString(),
141
+ drawn,
142
+ drawnUsd: new Dec(drawn).mul(price).toString(),
143
+ premium,
144
+ premiumUsd: new Dec(premium).mul(price).toString(),
145
+ borrowed,
146
+ borrowedUsd: new Dec(borrowed).mul(price).toString(),
147
+ isSupplied: !new Dec(supplied).eq(0),
148
+ isBorrowed: usedReserveAsset.isBorrowing,
149
+ collateral: usedReserveAsset.isUsingAsCollateral,
150
+ collateralFactor: new Dec(usedReserveAsset.collateralFactor).div(10000).toNumber(),
151
+ };
152
+ return acc;
153
+ }, {});
154
+
155
+ return {
156
+ usedAssets,
157
+ healthFactor,
158
+ ...aaveV4GetAggregatedPositionData({
159
+ usedAssets,
160
+ assetsData: spokeData.assetsData,
161
+ network,
162
+ useUserCollateralFactor: true,
163
+ }),
164
+ };
165
+ }
166
+
167
+ export async function getAaveV4AccountData(provider: EthereumProvider, network: NetworkNumber, marketData: AaveV4SpokeData, address: EthAddress, blockNumber: 'latest' | number = 'latest'): Promise<any> {
168
+ return _getAaveV4AccountData(getViemProvider(provider, network), network, marketData, address, blockNumber);
169
169
  }
@@ -1,155 +1,155 @@
1
- import { Client } from 'viem';
2
- import Dec from 'decimal.js';
3
- import { EthAddress, NetworkNumber } from '../types/common';
4
- import { ClaimableToken, ClaimType } from '../types/claiming';
5
- import {
6
- AaveIncentiveDataProviderV3ContractViem,
7
- AaveRewardsControllerViem,
8
- } from '../contracts';
9
- import { compareAddresses, getEthAmountForDecimals } from '../services/utils';
10
- import { getAaveUnderlyingSymbol } from '../helpers/aaveHelpers';
11
-
12
- type AaveReward = {
13
- amount: string;
14
- symbol: string;
15
- underlyingAsset: string;
16
- rewardTokenAddress: string;
17
- aTokenAddresses: string[];
18
- };
19
-
20
- const mapAaveRewardsToClaimableTokens = (aaveRewards: AaveReward[], marketAddress: EthAddress, walletAddress: EthAddress) => aaveRewards.map(reward => ({
21
- symbol: reward.symbol,
22
- amount: reward.amount,
23
- claimType: ClaimType.AAVE_REWARDS as const,
24
- tokenAddress: reward.rewardTokenAddress as EthAddress,
25
- underlyingSymbol: reward.underlyingAsset,
26
- walletAddress,
27
- label: 'AAVE Rewards',
28
- additionalClaimFields: {
29
- marketAddress,
30
- aTokenAddresses: reward.aTokenAddresses,
31
- isAaveToken: reward.symbol.startsWith('a'),
32
- },
33
- }));
34
-
35
- export async function getUnclaimedRewardsForAllMarkets(
36
- provider: Client,
37
- network: NetworkNumber,
38
- walletAddress: EthAddress,
39
- marketAddress: EthAddress,
40
- ): Promise<ClaimableToken[]> {
41
- const contract = AaveIncentiveDataProviderV3ContractViem(provider, network);
42
- const tokensData = await contract.read.getUserReservesIncentivesData([marketAddress, walletAddress]);
43
- const allTokensDataArrays = tokensData.reduce((acc: any[], val) => {
44
- acc.push(val.aTokenIncentivesUserData.userRewardsInformation);
45
- acc.push(val.vTokenIncentivesUserData.userRewardsInformation);
46
- return acc;
47
- }, []);
48
- const allATokens = tokensData.reduce((acc, val) => {
49
- acc.push(val.aTokenIncentivesUserData.tokenAddress);
50
- acc.push(val.vTokenIncentivesUserData.tokenAddress);
51
- return acc;
52
- }, [] as string[]);
53
- // array of rewards for each market (aToken/vToken)
54
- // reward can be any token like wstETH, but also aToken like aWETH
55
- const aaveRewardsController = AaveRewardsControllerViem(provider, network);
56
- const rewardsPerAAsset = await Promise.all(allATokens.map(
57
- (token: string) => aaveRewardsController.read.getAllUserRewards([[token as EthAddress], walletAddress])));
58
-
59
- // match amounts to token symbol, parse decimal amounts
60
- const rewardsPerAAssetWithInfo = rewardsPerAAsset.map((rewardForAAsset, aaIndex) => {
61
- const rewardsList = rewardForAAsset[0];
62
- const amounts = rewardForAAsset[1];
63
-
64
- const rewardsDataArraysForAAsset = allTokensDataArrays[aaIndex];
65
- const aTokenAddress = allATokens[aaIndex];
66
- return rewardsList.map((rewardTokenAddress, rewardIndex) => {
67
- const dataArrIndex = rewardsDataArraysForAAsset.findIndex((arr: { rewardTokenAddress: string | undefined; }) => compareAddresses(arr.rewardTokenAddress, rewardTokenAddress));
68
- const amountWei = amounts[rewardIndex];
69
- const amount = getEthAmountForDecimals(amountWei.toString(), rewardsDataArraysForAAsset[dataArrIndex]?.rewardTokenDecimals);
70
- const symbol = rewardsDataArraysForAAsset[dataArrIndex]?.rewardTokenSymbol || '';
71
- const underlyingAsset = getAaveUnderlyingSymbol(symbol);
72
- return ({
73
- amount,
74
- symbol,
75
- underlyingAsset,
76
- rewardTokenAddress,
77
- aTokenAddress,
78
- });
79
- });
80
- });
81
-
82
- // sum all unclaimed rewards of all markets per each token
83
- // (e.g. how much awstETH is claimable in total from both aUSDC and awstETH markets)
84
- const totalUnclaimedPerRewardToken: Record<string, any> = {};
85
- rewardsPerAAssetWithInfo
86
- .flat()
87
- .forEach(({
88
- amount, symbol, underlyingAsset, rewardTokenAddress, aTokenAddress,
89
- }) => {
90
- if (+amount > 0) {
91
- if (!totalUnclaimedPerRewardToken[symbol]) {
92
- totalUnclaimedPerRewardToken[symbol] = {
93
- amount, symbol, underlyingAsset, rewardTokenAddress, aTokenAddresses: [aTokenAddress],
94
- };
95
- } else {
96
- totalUnclaimedPerRewardToken[symbol].amount =
97
- new Dec(totalUnclaimedPerRewardToken[symbol].amount).add(amount).toString();
98
- totalUnclaimedPerRewardToken[symbol].aTokenAddresses.push(aTokenAddress);
99
- }
100
- }
101
- }, []);
102
-
103
- return mapAaveRewardsToClaimableTokens(Object.values(totalUnclaimedPerRewardToken), marketAddress, walletAddress);
104
- }
105
-
106
- export async function getMeritUnclaimedRewards(account: EthAddress, network: NetworkNumber, acceptMorpho: boolean = true): Promise<ClaimableToken[]> {
107
- let data;
108
- try {
109
- const res = await fetch(`https://api.merkl.xyz/v4/users/${account}/rewards?chainId=${network}`,
110
- { signal: AbortSignal.timeout(3000) });
111
- data = await res.json();
112
- } catch (error) {
113
- console.error('External API Failure: Aave Merit', error);
114
- data = [];
115
- }
116
-
117
- const claimableTokens: ClaimableToken[] = [];
118
-
119
- data.forEach((item: { rewards: any[]; }) => {
120
- item.rewards.forEach(reward => {
121
- const {
122
- token,
123
- amount,
124
- claimed,
125
- proofs,
126
- } = reward;
127
-
128
- const isTokenMorpho = token.symbol === 'MORPHO';
129
- if (!token || !token.symbol || amount === '0' || (isTokenMorpho && !acceptMorpho)) return;
130
-
131
- const unclaimedAmount = new Dec(amount).minus(claimed || 0).toString();
132
- if (unclaimedAmount === '0') return;
133
-
134
- const unclaimed = getEthAmountForDecimals(unclaimedAmount, token.decimals);
135
-
136
- claimableTokens.push({
137
- claimType: ClaimType.AAVE_MERIT_REWARDS,
138
- amount: unclaimed,
139
- symbol: token.symbol,
140
- tokenAddress: token.address,
141
- walletAddress: account,
142
- label: 'AAVE Merit Rewards',
143
- underlyingSymbol: getAaveUnderlyingSymbol(token.symbol),
144
- additionalClaimFields: {
145
- accumulated: amount,
146
- proof: proofs,
147
- decimals: token.decimals,
148
- unclaimed: unclaimedAmount,
149
- },
150
- });
151
- });
152
- });
153
-
154
- return claimableTokens;
1
+ import { Client } from 'viem';
2
+ import Dec from 'decimal.js';
3
+ import { EthAddress, NetworkNumber } from '../types/common';
4
+ import { ClaimableToken, ClaimType } from '../types/claiming';
5
+ import {
6
+ AaveIncentiveDataProviderV3ContractViem,
7
+ AaveRewardsControllerViem,
8
+ } from '../contracts';
9
+ import { compareAddresses, getEthAmountForDecimals } from '../services/utils';
10
+ import { getAaveUnderlyingSymbol } from '../helpers/aaveHelpers';
11
+
12
+ type AaveReward = {
13
+ amount: string;
14
+ symbol: string;
15
+ underlyingAsset: string;
16
+ rewardTokenAddress: string;
17
+ aTokenAddresses: string[];
18
+ };
19
+
20
+ const mapAaveRewardsToClaimableTokens = (aaveRewards: AaveReward[], marketAddress: EthAddress, walletAddress: EthAddress) => aaveRewards.map(reward => ({
21
+ symbol: reward.symbol,
22
+ amount: reward.amount,
23
+ claimType: ClaimType.AAVE_REWARDS as const,
24
+ tokenAddress: reward.rewardTokenAddress as EthAddress,
25
+ underlyingSymbol: reward.underlyingAsset,
26
+ walletAddress,
27
+ label: 'AAVE Rewards',
28
+ additionalClaimFields: {
29
+ marketAddress,
30
+ aTokenAddresses: reward.aTokenAddresses,
31
+ isAaveToken: reward.symbol.startsWith('a'),
32
+ },
33
+ }));
34
+
35
+ export async function getUnclaimedRewardsForAllMarkets(
36
+ provider: Client,
37
+ network: NetworkNumber,
38
+ walletAddress: EthAddress,
39
+ marketAddress: EthAddress,
40
+ ): Promise<ClaimableToken[]> {
41
+ const contract = AaveIncentiveDataProviderV3ContractViem(provider, network);
42
+ const tokensData = await contract.read.getUserReservesIncentivesData([marketAddress, walletAddress]);
43
+ const allTokensDataArrays = tokensData.reduce((acc: any[], val) => {
44
+ acc.push(val.aTokenIncentivesUserData.userRewardsInformation);
45
+ acc.push(val.vTokenIncentivesUserData.userRewardsInformation);
46
+ return acc;
47
+ }, []);
48
+ const allATokens = tokensData.reduce((acc, val) => {
49
+ acc.push(val.aTokenIncentivesUserData.tokenAddress);
50
+ acc.push(val.vTokenIncentivesUserData.tokenAddress);
51
+ return acc;
52
+ }, [] as string[]);
53
+ // array of rewards for each market (aToken/vToken)
54
+ // reward can be any token like wstETH, but also aToken like aWETH
55
+ const aaveRewardsController = AaveRewardsControllerViem(provider, network);
56
+ const rewardsPerAAsset = await Promise.all(allATokens.map(
57
+ (token: string) => aaveRewardsController.read.getAllUserRewards([[token as EthAddress], walletAddress])));
58
+
59
+ // match amounts to token symbol, parse decimal amounts
60
+ const rewardsPerAAssetWithInfo = rewardsPerAAsset.map((rewardForAAsset, aaIndex) => {
61
+ const rewardsList = rewardForAAsset[0];
62
+ const amounts = rewardForAAsset[1];
63
+
64
+ const rewardsDataArraysForAAsset = allTokensDataArrays[aaIndex];
65
+ const aTokenAddress = allATokens[aaIndex];
66
+ return rewardsList.map((rewardTokenAddress, rewardIndex) => {
67
+ const dataArrIndex = rewardsDataArraysForAAsset.findIndex((arr: { rewardTokenAddress: string | undefined; }) => compareAddresses(arr.rewardTokenAddress, rewardTokenAddress));
68
+ const amountWei = amounts[rewardIndex];
69
+ const amount = getEthAmountForDecimals(amountWei.toString(), rewardsDataArraysForAAsset[dataArrIndex]?.rewardTokenDecimals);
70
+ const symbol = rewardsDataArraysForAAsset[dataArrIndex]?.rewardTokenSymbol || '';
71
+ const underlyingAsset = getAaveUnderlyingSymbol(symbol);
72
+ return ({
73
+ amount,
74
+ symbol,
75
+ underlyingAsset,
76
+ rewardTokenAddress,
77
+ aTokenAddress,
78
+ });
79
+ });
80
+ });
81
+
82
+ // sum all unclaimed rewards of all markets per each token
83
+ // (e.g. how much awstETH is claimable in total from both aUSDC and awstETH markets)
84
+ const totalUnclaimedPerRewardToken: Record<string, any> = {};
85
+ rewardsPerAAssetWithInfo
86
+ .flat()
87
+ .forEach(({
88
+ amount, symbol, underlyingAsset, rewardTokenAddress, aTokenAddress,
89
+ }) => {
90
+ if (+amount > 0) {
91
+ if (!totalUnclaimedPerRewardToken[symbol]) {
92
+ totalUnclaimedPerRewardToken[symbol] = {
93
+ amount, symbol, underlyingAsset, rewardTokenAddress, aTokenAddresses: [aTokenAddress],
94
+ };
95
+ } else {
96
+ totalUnclaimedPerRewardToken[symbol].amount =
97
+ new Dec(totalUnclaimedPerRewardToken[symbol].amount).add(amount).toString();
98
+ totalUnclaimedPerRewardToken[symbol].aTokenAddresses.push(aTokenAddress);
99
+ }
100
+ }
101
+ }, []);
102
+
103
+ return mapAaveRewardsToClaimableTokens(Object.values(totalUnclaimedPerRewardToken), marketAddress, walletAddress);
104
+ }
105
+
106
+ export async function getMeritUnclaimedRewards(account: EthAddress, network: NetworkNumber, acceptMorpho: boolean = true): Promise<ClaimableToken[]> {
107
+ let data;
108
+ try {
109
+ const res = await fetch(`https://api.merkl.xyz/v4/users/${account}/rewards?chainId=${network}`,
110
+ { signal: AbortSignal.timeout(3000) });
111
+ data = await res.json();
112
+ } catch (error) {
113
+ console.error('External API Failure: Aave Merit', error);
114
+ data = [];
115
+ }
116
+
117
+ const claimableTokens: ClaimableToken[] = [];
118
+
119
+ data.forEach((item: { rewards: any[]; }) => {
120
+ item.rewards.forEach(reward => {
121
+ const {
122
+ token,
123
+ amount,
124
+ claimed,
125
+ proofs,
126
+ } = reward;
127
+
128
+ const isTokenMorpho = token.symbol === 'MORPHO';
129
+ if (!token || !token.symbol || amount === '0' || (isTokenMorpho && !acceptMorpho)) return;
130
+
131
+ const unclaimedAmount = new Dec(amount).minus(claimed || 0).toString();
132
+ if (unclaimedAmount === '0') return;
133
+
134
+ const unclaimed = getEthAmountForDecimals(unclaimedAmount, token.decimals);
135
+
136
+ claimableTokens.push({
137
+ claimType: ClaimType.AAVE_MERIT_REWARDS,
138
+ amount: unclaimed,
139
+ symbol: token.symbol,
140
+ tokenAddress: token.address,
141
+ walletAddress: account,
142
+ label: 'AAVE Merit Rewards',
143
+ underlyingSymbol: getAaveUnderlyingSymbol(token.symbol),
144
+ additionalClaimFields: {
145
+ accumulated: amount,
146
+ proof: proofs,
147
+ decimals: token.decimals,
148
+ unclaimed: unclaimedAmount,
149
+ },
150
+ });
151
+ });
152
+ });
153
+
154
+ return claimableTokens;
155
155
  }