@defisaver/positions-sdk 2.1.6 → 2.1.8

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 (132) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/aaveV3/index.js +3 -3
  5. package/cjs/aaveV3/merit.js +5 -3
  6. package/cjs/aaveV3/merkl.d.ts +1 -1
  7. package/cjs/config/contracts.d.ts +23 -0
  8. package/cjs/config/contracts.js +23 -0
  9. package/cjs/helpers/aaveHelpers/index.d.ts +1 -1
  10. package/cjs/helpers/aaveHelpers/index.js +6 -4
  11. package/cjs/helpers/morphoBlueHelpers/index.d.ts +1 -1
  12. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  13. package/cjs/markets/aave/index.js +1 -1
  14. package/cjs/markets/aave/marketAssets.d.ts +4 -0
  15. package/cjs/markets/aave/marketAssets.js +5 -1
  16. package/cjs/markets/compound/index.js +11 -0
  17. package/cjs/markets/compound/marketsAssets.d.ts +7 -0
  18. package/cjs/markets/compound/marketsAssets.js +7 -0
  19. package/cjs/markets/spark/marketAssets.d.ts +1 -0
  20. package/cjs/markets/spark/marketAssets.js +1 -0
  21. package/cjs/services/utils.d.ts +8 -4
  22. package/cjs/services/utils.js +30 -10
  23. package/cjs/services/viem.d.ts +54 -15
  24. package/cjs/services/viem.js +2 -0
  25. package/cjs/staking/eligibility.js +1 -6
  26. package/cjs/types/common.d.ts +4 -2
  27. package/cjs/types/common.js +2 -0
  28. package/esm/aaveV3/index.js +4 -4
  29. package/esm/aaveV3/merit.js +5 -3
  30. package/esm/aaveV3/merkl.d.ts +1 -1
  31. package/esm/config/contracts.d.ts +23 -0
  32. package/esm/config/contracts.js +23 -0
  33. package/esm/helpers/aaveHelpers/index.d.ts +1 -1
  34. package/esm/helpers/aaveHelpers/index.js +7 -5
  35. package/esm/helpers/morphoBlueHelpers/index.d.ts +1 -1
  36. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  37. package/esm/markets/aave/index.js +1 -1
  38. package/esm/markets/aave/marketAssets.d.ts +4 -0
  39. package/esm/markets/aave/marketAssets.js +4 -0
  40. package/esm/markets/compound/index.js +11 -0
  41. package/esm/markets/compound/marketsAssets.d.ts +7 -0
  42. package/esm/markets/compound/marketsAssets.js +7 -0
  43. package/esm/markets/spark/marketAssets.d.ts +1 -0
  44. package/esm/markets/spark/marketAssets.js +1 -0
  45. package/esm/services/utils.d.ts +8 -4
  46. package/esm/services/utils.js +21 -5
  47. package/esm/services/viem.d.ts +54 -15
  48. package/esm/services/viem.js +3 -1
  49. package/esm/staking/eligibility.js +1 -6
  50. package/esm/types/common.d.ts +4 -2
  51. package/esm/types/common.js +2 -0
  52. package/package.json +47 -47
  53. package/src/aaveV2/index.ts +240 -240
  54. package/src/aaveV3/index.ts +614 -614
  55. package/src/aaveV3/merit.ts +97 -94
  56. package/src/aaveV3/merkl.ts +74 -74
  57. package/src/claiming/aaveV3.ts +154 -154
  58. package/src/claiming/compV3.ts +22 -22
  59. package/src/claiming/index.ts +12 -12
  60. package/src/claiming/king.ts +66 -66
  61. package/src/claiming/morphoBlue.ts +118 -118
  62. package/src/claiming/spark.ts +225 -225
  63. package/src/compoundV2/index.ts +244 -244
  64. package/src/compoundV3/index.ts +274 -274
  65. package/src/config/contracts.ts +1251 -1228
  66. package/src/constants/index.ts +10 -10
  67. package/src/contracts.ts +120 -120
  68. package/src/curveUsd/index.ts +254 -254
  69. package/src/eulerV2/index.ts +324 -324
  70. package/src/exchange/index.ts +25 -25
  71. package/src/fluid/index.ts +1638 -1638
  72. package/src/helpers/aaveHelpers/index.ts +187 -185
  73. package/src/helpers/compoundHelpers/index.ts +283 -283
  74. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  75. package/src/helpers/eulerHelpers/index.ts +222 -222
  76. package/src/helpers/fluidHelpers/index.ts +326 -326
  77. package/src/helpers/index.ts +10 -10
  78. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  79. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  80. package/src/helpers/makerHelpers/index.ts +52 -52
  81. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  82. package/src/helpers/sparkHelpers/index.ts +155 -155
  83. package/src/index.ts +47 -47
  84. package/src/liquity/index.ts +159 -159
  85. package/src/liquityV2/index.ts +657 -657
  86. package/src/llamaLend/index.ts +305 -305
  87. package/src/maker/index.ts +223 -223
  88. package/src/markets/aave/index.ts +116 -116
  89. package/src/markets/aave/marketAssets.ts +54 -49
  90. package/src/markets/compound/index.ts +238 -227
  91. package/src/markets/compound/marketsAssets.ts +97 -90
  92. package/src/markets/curveUsd/index.ts +69 -69
  93. package/src/markets/euler/index.ts +26 -26
  94. package/src/markets/fluid/index.ts +2456 -2456
  95. package/src/markets/index.ts +25 -25
  96. package/src/markets/liquityV2/index.ts +102 -102
  97. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  98. package/src/markets/llamaLend/index.ts +235 -235
  99. package/src/markets/morphoBlue/index.ts +895 -895
  100. package/src/markets/spark/index.ts +29 -29
  101. package/src/markets/spark/marketAssets.ts +12 -11
  102. package/src/moneymarket/moneymarketCommonService.ts +80 -80
  103. package/src/morphoBlue/index.ts +274 -274
  104. package/src/portfolio/index.ts +570 -570
  105. package/src/services/priceService.ts +159 -159
  106. package/src/services/utils.ts +115 -99
  107. package/src/services/viem.ts +34 -32
  108. package/src/setup.ts +8 -8
  109. package/src/spark/index.ts +445 -445
  110. package/src/staking/eligibility.ts +53 -59
  111. package/src/staking/index.ts +1 -1
  112. package/src/staking/staking.ts +170 -170
  113. package/src/types/aave.ts +189 -189
  114. package/src/types/claiming.ts +109 -109
  115. package/src/types/common.ts +107 -105
  116. package/src/types/compound.ts +136 -136
  117. package/src/types/curveUsd.ts +123 -123
  118. package/src/types/euler.ts +175 -175
  119. package/src/types/fluid.ts +448 -448
  120. package/src/types/index.ts +13 -13
  121. package/src/types/liquity.ts +30 -30
  122. package/src/types/liquityV2.ts +126 -126
  123. package/src/types/llamaLend.ts +159 -159
  124. package/src/types/maker.ts +63 -63
  125. package/src/types/merit.ts +1 -1
  126. package/src/types/merkl.ts +70 -70
  127. package/src/types/morphoBlue.ts +194 -194
  128. package/src/types/portfolio.ts +60 -60
  129. package/src/types/spark.ts +135 -135
  130. package/src/umbrella/index.ts +69 -69
  131. package/src/umbrella/umbrellaUtils.ts +29 -29
  132. package/CLAUDE.md +0 -32
@@ -1,23 +1,23 @@
1
- import { Client } from 'viem';
2
- import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
3
- import { EthAddress, NetworkNumber } from '../types/common';
4
- import { CompV3ViewContractViem } from '../contracts';
5
- import { ClaimType } from '../types/claiming';
6
-
7
- export const getCompoundV3Rewards = async (provider: Client, network: NetworkNumber, user: EthAddress, market: any) => {
8
- const compV3View = CompV3ViewContractViem(provider, network);
9
- const rewards = await compV3View.read.getRewardsOwed([market, user]);
10
- if (!rewards || rewards.owed.toString() === '0' || getAssetInfoByAddress(rewards.token, network).symbol !== 'COMP') return [];
11
- return [{
12
- symbol: 'COMP',
13
- underlyingSymbol: 'COMP',
14
- tokenAddress: rewards.token,
15
- amount: assetAmountInEth(rewards.owed.toString() || 0, 'COMP'),
16
- walletAddress: user,
17
- label: 'Compound V3',
18
- claimType: ClaimType.COMPOUND_V3_COMP,
19
- additionalClaimFields: {
20
- marketAddress: market,
21
- },
22
- }];
1
+ import { Client } from 'viem';
2
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
3
+ import { EthAddress, NetworkNumber } from '../types/common';
4
+ import { CompV3ViewContractViem } from '../contracts';
5
+ import { ClaimType } from '../types/claiming';
6
+
7
+ export const getCompoundV3Rewards = async (provider: Client, network: NetworkNumber, user: EthAddress, market: any) => {
8
+ const compV3View = CompV3ViewContractViem(provider, network);
9
+ const rewards = await compV3View.read.getRewardsOwed([market, user]);
10
+ if (!rewards || rewards.owed.toString() === '0' || getAssetInfoByAddress(rewards.token, network).symbol !== 'COMP') return [];
11
+ return [{
12
+ symbol: 'COMP',
13
+ underlyingSymbol: 'COMP',
14
+ tokenAddress: rewards.token,
15
+ amount: assetAmountInEth(rewards.owed.toString() || 0, 'COMP'),
16
+ walletAddress: user,
17
+ label: 'Compound V3',
18
+ claimType: ClaimType.COMPOUND_V3_COMP,
19
+ additionalClaimFields: {
20
+ marketAddress: market,
21
+ },
22
+ }];
23
23
  };
@@ -1,13 +1,13 @@
1
- import * as aaveV3Claim from './aaveV3';
2
- import * as compV3Claim from './compV3';
3
- import * as kingV3Claim from './king';
4
- import * as morphoBlueClaim from './morphoBlue';
5
- import * as sparkClaim from './spark';
6
-
7
- export {
8
- aaveV3Claim,
9
- compV3Claim,
10
- kingV3Claim,
11
- morphoBlueClaim,
12
- sparkClaim,
1
+ import * as aaveV3Claim from './aaveV3';
2
+ import * as compV3Claim from './compV3';
3
+ import * as kingV3Claim from './king';
4
+ import * as morphoBlueClaim from './morphoBlue';
5
+ import * as sparkClaim from './spark';
6
+
7
+ export {
8
+ aaveV3Claim,
9
+ compV3Claim,
10
+ kingV3Claim,
11
+ morphoBlueClaim,
12
+ sparkClaim,
13
13
  };
@@ -1,66 +1,66 @@
1
- import Dec from 'decimal.js';
2
- import { assetAmountInEth } from '@defisaver/tokens';
3
- import { Client } from 'viem';
4
- import { UUPSViem } from '../contracts';
5
- import { EthAddress, HexString, NetworkNumber } from '../types/common';
6
- import { ClaimType } from '../types/claiming';
7
-
8
- export const fetchKingRewards = async (walletAddress: EthAddress) => {
9
- try {
10
- const res = await fetch(`https://fe.defisaver.com/api/etherfi/get-king-rewards/${walletAddress}`,
11
- { signal: AbortSignal.timeout(5000) });
12
-
13
- if (!res.ok) throw new Error(await res.text());
14
-
15
- return await res.json();
16
- } catch (err) {
17
- console.error('External API Error: Error fetching KING rewards:', err);
18
- return { Amount: '0', Root: '', Proofs: [] };
19
- }
20
- };
21
-
22
- export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => {
23
- // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
24
- const apiDataPromises = walletAddresses.map(address => fetchKingRewards(address));
25
- const apiDataArray = await Promise.all(apiDataPromises);
26
-
27
- // Batch all contract calls using multicall
28
- const contract = UUPSViem(provider, network);
29
- const cumulativePromises = walletAddresses.map(address => contract.read.cumulativeClaimed([address]),
30
- );
31
- const cumulativeResults = await Promise.all(cumulativePromises);
32
-
33
- // Process results
34
- const results: Record<string, any[]> = {};
35
-
36
- for (let i = 0; i < walletAddresses.length; i++) {
37
- const walletAddress = walletAddresses[i];
38
- const data = apiDataArray[i];
39
- const cumulative = cumulativeResults[i];
40
-
41
- const allRewardsAmount = assetAmountInEth(data.Amount, 'KING');
42
- const claimedAmount = assetAmountInEth(cumulative.toString(), 'KING');
43
- const amountToClaim = new Dec(allRewardsAmount).sub(claimedAmount);
44
-
45
- if (amountToClaim.lessThanOrEqualTo('0')) {
46
- results[walletAddress.toLowerCase() as EthAddress] = [];
47
- } else {
48
- results[walletAddress.toLowerCase() as EthAddress] = [{
49
- symbol: 'KING',
50
- underlyingSymbol: 'KING',
51
- tokenAddress: '0x8F08B70456eb22f6109F57b8fafE862ED28E6040',
52
- amount: amountToClaim.toString(),
53
- walletAddress,
54
- label: 'weETH',
55
- claimType: ClaimType.KING_REWARDS,
56
- additionalClaimFields: {
57
- allRewardsAmount,
58
- merkleRoot: data.Root,
59
- merkleProofs: data.Proofs,
60
- },
61
- }];
62
- }
63
- }
64
-
65
- return results;
66
- };
1
+ import Dec from 'decimal.js';
2
+ import { assetAmountInEth } from '@defisaver/tokens';
3
+ import { Client } from 'viem';
4
+ import { UUPSViem } from '../contracts';
5
+ import { EthAddress, HexString, NetworkNumber } from '../types/common';
6
+ import { ClaimType } from '../types/claiming';
7
+
8
+ export const fetchKingRewards = async (walletAddress: EthAddress) => {
9
+ try {
10
+ const res = await fetch(`https://fe.defisaver.com/api/etherfi/get-king-rewards/${walletAddress}`,
11
+ { signal: AbortSignal.timeout(5000) });
12
+
13
+ if (!res.ok) throw new Error(await res.text());
14
+
15
+ return await res.json();
16
+ } catch (err) {
17
+ console.error('External API Error: Error fetching KING rewards:', err);
18
+ return { Amount: '0', Root: '', Proofs: [] };
19
+ }
20
+ };
21
+
22
+ export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => {
23
+ // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
24
+ const apiDataPromises = walletAddresses.map(address => fetchKingRewards(address));
25
+ const apiDataArray = await Promise.all(apiDataPromises);
26
+
27
+ // Batch all contract calls using multicall
28
+ const contract = UUPSViem(provider, network);
29
+ const cumulativePromises = walletAddresses.map(address => contract.read.cumulativeClaimed([address]),
30
+ );
31
+ const cumulativeResults = await Promise.all(cumulativePromises);
32
+
33
+ // Process results
34
+ const results: Record<string, any[]> = {};
35
+
36
+ for (let i = 0; i < walletAddresses.length; i++) {
37
+ const walletAddress = walletAddresses[i];
38
+ const data = apiDataArray[i];
39
+ const cumulative = cumulativeResults[i];
40
+
41
+ const allRewardsAmount = assetAmountInEth(data.Amount, 'KING');
42
+ const claimedAmount = assetAmountInEth(cumulative.toString(), 'KING');
43
+ const amountToClaim = new Dec(allRewardsAmount).sub(claimedAmount);
44
+
45
+ if (amountToClaim.lessThanOrEqualTo('0')) {
46
+ results[walletAddress.toLowerCase() as EthAddress] = [];
47
+ } else {
48
+ results[walletAddress.toLowerCase() as EthAddress] = [{
49
+ symbol: 'KING',
50
+ underlyingSymbol: 'KING',
51
+ tokenAddress: '0x8F08B70456eb22f6109F57b8fafE862ED28E6040',
52
+ amount: amountToClaim.toString(),
53
+ walletAddress,
54
+ label: 'weETH',
55
+ claimType: ClaimType.KING_REWARDS,
56
+ additionalClaimFields: {
57
+ allRewardsAmount,
58
+ merkleRoot: data.Root,
59
+ merkleProofs: data.Proofs,
60
+ },
61
+ }];
62
+ }
63
+ }
64
+
65
+ return results;
66
+ };
@@ -1,119 +1,119 @@
1
- import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
2
- import { Client } from 'viem';
3
- import Dec from 'decimal.js';
4
- import { ClaimableToken, ClaimType } from '../types/claiming';
5
- import { EthAddress, NetworkNumber } from '../types/common';
6
- import { createViemContractFromConfigFunc } from '../contracts';
7
- import { getMorphoUnderlyingSymbol } from '../helpers/morphoBlueHelpers';
8
-
9
- const MORPHO_ALLOWED_CONTRACTS = [
10
- '0x330eefa8a787552DC5cAd3C3cA644844B1E61Ddb',
11
- '0x678dDC1d07eaa166521325394cDEb1E4c086DF43',
12
- '0x2efd4625d0c149ebadf118ec5446c6de24d916a4',
13
- ];
14
-
15
- const MORPHO_ALLOWED_TOKENS = [
16
- 'MORPHO',
17
- 'MORPHO Legacy',
18
- ];
19
-
20
-
21
- export const getMorphoBlueRewardsInfo = async (address: EthAddress) => {
22
- if (!address) return { claimable: '0' };
23
-
24
- try {
25
- const res = await fetch(`https://rewards.morpho.org/v1/users/${address}/distributions`,
26
- { signal: AbortSignal.timeout(3000) });
27
-
28
- if (!res.ok) throw new Error(await res.text());
29
- return await res.json();
30
- } catch (error) {
31
- console.error('External API Failure: Morpho Merit', error);
32
- return { claimable: '0' };
33
- }
34
- };
35
-
36
- export const fetchMorphoBlueRewards = async (
37
- provider: Client,
38
- network: NetworkNumber,
39
- walletAddresses: EthAddress[],
40
- ): Promise<Record<string, ClaimableToken[]>> => {
41
- // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
42
- const apiDataPromises = walletAddresses.map(address => getMorphoBlueRewardsInfo(address));
43
- const apiDataArray = await Promise.all(apiDataPromises);
44
-
45
- // Process API data to get claimable tokens for each wallet
46
- const allClaimableTokens: Array<{ walletAddress: EthAddress; tokens: ClaimableToken[] }> = [];
47
- const contractCallsData: Array<{ walletAddress: EthAddress; tokenAddress: EthAddress; distributor: EthAddress }> = [];
48
-
49
- for (let i = 0; i < walletAddresses.length; i++) {
50
- const walletAddress = walletAddresses[i];
51
- const data = apiDataArray[i];
52
-
53
- const claimableTokens = data?.data?.reduce((acc: ClaimableToken[], reward: any) => {
54
- const token = getAssetInfoByAddress(reward.asset.address);
55
- if (!MORPHO_ALLOWED_CONTRACTS.includes(reward?.distributor?.address) || !MORPHO_ALLOWED_TOKENS.includes(token.symbol)) {
56
- return acc;
57
- }
58
-
59
- // Store contract call data for batching
60
- contractCallsData.push({
61
- walletAddress,
62
- tokenAddress: reward.asset.address,
63
- distributor: reward?.distributor?.address,
64
- });
65
-
66
- return [
67
- ...acc,
68
- {
69
- symbol: token.symbol,
70
- underlyingSymbol: getMorphoUnderlyingSymbol(token.symbol),
71
- tokenAddress: reward.asset.address,
72
- amount: assetAmountInEth(reward.claimable, token.symbol),
73
- walletAddress,
74
- label: token.symbol,
75
- claimType: ClaimType.MORPHO,
76
- additionalClaimFields: {
77
- originalAmount: reward.claimable,
78
- distributor: reward?.distributor?.address,
79
- merkleProofs: reward?.proof,
80
- isLegacy: token.symbol === 'MORPHO Legacy',
81
- txData: reward?.tx_data,
82
- },
83
- }];
84
- }, []) || [];
85
-
86
- allClaimableTokens.push({ walletAddress, tokens: claimableTokens });
87
- }
88
-
89
- // Batch all contract calls using multicall
90
- const contractPromises = contractCallsData.map(({ walletAddress, tokenAddress, distributor }) => {
91
- const distributorContract = createViemContractFromConfigFunc('MorphoDistributor', distributor)(provider, network);
92
- return distributorContract.read.claimed([walletAddress, tokenAddress]);
93
- });
94
- const contractResults = await Promise.all(contractPromises);
95
-
96
- // Process results
97
- const results: Record<string, ClaimableToken[]> = {};
98
- let contractCallIndex = 0;
99
-
100
- for (const { walletAddress, tokens } of allClaimableTokens) {
101
- const updatedTokens: ClaimableToken[] = [];
102
-
103
- for (let i = 0; i < tokens.length; i++) {
104
- const claimableToken = tokens[i];
105
- const claimed = assetAmountInEth(contractResults[contractCallIndex].toString(), claimableToken.underlyingSymbol);
106
- contractCallIndex++;
107
-
108
- const updatedToken = { ...claimableToken };
109
- updatedToken.amount = new Dec(claimableToken.amount).sub(claimed).toString();
110
- updatedTokens.push(updatedToken);
111
- }
112
-
113
- results[walletAddress.toLowerCase() as EthAddress] = updatedTokens.filter(
114
- (claimableToken) => new Dec(claimableToken.amount).gt(0),
115
- );
116
- }
117
-
118
- return results;
1
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
2
+ import { Client } from 'viem';
3
+ import Dec from 'decimal.js';
4
+ import { ClaimableToken, ClaimType } from '../types/claiming';
5
+ import { EthAddress, NetworkNumber } from '../types/common';
6
+ import { createViemContractFromConfigFunc } from '../contracts';
7
+ import { getMorphoUnderlyingSymbol } from '../helpers/morphoBlueHelpers';
8
+
9
+ const MORPHO_ALLOWED_CONTRACTS = [
10
+ '0x330eefa8a787552DC5cAd3C3cA644844B1E61Ddb',
11
+ '0x678dDC1d07eaa166521325394cDEb1E4c086DF43',
12
+ '0x2efd4625d0c149ebadf118ec5446c6de24d916a4',
13
+ ];
14
+
15
+ const MORPHO_ALLOWED_TOKENS = [
16
+ 'MORPHO',
17
+ 'MORPHO Legacy',
18
+ ];
19
+
20
+
21
+ export const getMorphoBlueRewardsInfo = async (address: EthAddress) => {
22
+ if (!address) return { claimable: '0' };
23
+
24
+ try {
25
+ const res = await fetch(`https://rewards.morpho.org/v1/users/${address}/distributions`,
26
+ { signal: AbortSignal.timeout(3000) });
27
+
28
+ if (!res.ok) throw new Error(await res.text());
29
+ return await res.json();
30
+ } catch (error) {
31
+ console.error('External API Failure: Morpho Merit', error);
32
+ return { claimable: '0' };
33
+ }
34
+ };
35
+
36
+ export const fetchMorphoBlueRewards = async (
37
+ provider: Client,
38
+ network: NetworkNumber,
39
+ walletAddresses: EthAddress[],
40
+ ): Promise<Record<string, ClaimableToken[]>> => {
41
+ // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
42
+ const apiDataPromises = walletAddresses.map(address => getMorphoBlueRewardsInfo(address));
43
+ const apiDataArray = await Promise.all(apiDataPromises);
44
+
45
+ // Process API data to get claimable tokens for each wallet
46
+ const allClaimableTokens: Array<{ walletAddress: EthAddress; tokens: ClaimableToken[] }> = [];
47
+ const contractCallsData: Array<{ walletAddress: EthAddress; tokenAddress: EthAddress; distributor: EthAddress }> = [];
48
+
49
+ for (let i = 0; i < walletAddresses.length; i++) {
50
+ const walletAddress = walletAddresses[i];
51
+ const data = apiDataArray[i];
52
+
53
+ const claimableTokens = data?.data?.reduce((acc: ClaimableToken[], reward: any) => {
54
+ const token = getAssetInfoByAddress(reward.asset.address);
55
+ if (!MORPHO_ALLOWED_CONTRACTS.includes(reward?.distributor?.address) || !MORPHO_ALLOWED_TOKENS.includes(token.symbol)) {
56
+ return acc;
57
+ }
58
+
59
+ // Store contract call data for batching
60
+ contractCallsData.push({
61
+ walletAddress,
62
+ tokenAddress: reward.asset.address,
63
+ distributor: reward?.distributor?.address,
64
+ });
65
+
66
+ return [
67
+ ...acc,
68
+ {
69
+ symbol: token.symbol,
70
+ underlyingSymbol: getMorphoUnderlyingSymbol(token.symbol),
71
+ tokenAddress: reward.asset.address,
72
+ amount: assetAmountInEth(reward.claimable, token.symbol),
73
+ walletAddress,
74
+ label: token.symbol,
75
+ claimType: ClaimType.MORPHO,
76
+ additionalClaimFields: {
77
+ originalAmount: reward.claimable,
78
+ distributor: reward?.distributor?.address,
79
+ merkleProofs: reward?.proof,
80
+ isLegacy: token.symbol === 'MORPHO Legacy',
81
+ txData: reward?.tx_data,
82
+ },
83
+ }];
84
+ }, []) || [];
85
+
86
+ allClaimableTokens.push({ walletAddress, tokens: claimableTokens });
87
+ }
88
+
89
+ // Batch all contract calls using multicall
90
+ const contractPromises = contractCallsData.map(({ walletAddress, tokenAddress, distributor }) => {
91
+ const distributorContract = createViemContractFromConfigFunc('MorphoDistributor', distributor)(provider, network);
92
+ return distributorContract.read.claimed([walletAddress, tokenAddress]);
93
+ });
94
+ const contractResults = await Promise.all(contractPromises);
95
+
96
+ // Process results
97
+ const results: Record<string, ClaimableToken[]> = {};
98
+ let contractCallIndex = 0;
99
+
100
+ for (const { walletAddress, tokens } of allClaimableTokens) {
101
+ const updatedTokens: ClaimableToken[] = [];
102
+
103
+ for (let i = 0; i < tokens.length; i++) {
104
+ const claimableToken = tokens[i];
105
+ const claimed = assetAmountInEth(contractResults[contractCallIndex].toString(), claimableToken.underlyingSymbol);
106
+ contractCallIndex++;
107
+
108
+ const updatedToken = { ...claimableToken };
109
+ updatedToken.amount = new Dec(claimableToken.amount).sub(claimed).toString();
110
+ updatedTokens.push(updatedToken);
111
+ }
112
+
113
+ results[walletAddress.toLowerCase() as EthAddress] = updatedTokens.filter(
114
+ (claimableToken) => new Dec(claimableToken.amount).gt(0),
115
+ );
116
+ }
117
+
118
+ return results;
119
119
  };