@defisaver/positions-sdk 2.1.168-stable-pair-dev → 2.1.169-portfolio-api-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 (105) hide show
  1. package/cjs/aaveV3/index.d.ts +2 -12
  2. package/cjs/aaveV3/sgho.d.ts +2 -16
  3. package/cjs/aaveV4/lend.d.ts +2 -43
  4. package/cjs/claiming/aaveV3.d.ts +2 -2
  5. package/cjs/claiming/ethena.d.ts +2 -1
  6. package/cjs/claiming/king.d.ts +2 -1
  7. package/cjs/claiming/spark.d.ts +2 -2
  8. package/cjs/fluid/index.d.ts +5 -49
  9. package/cjs/helpers/aaveV4Helpers/index.js +1 -11
  10. package/cjs/liquity/index.d.ts +2 -12
  11. package/cjs/liquityV2/index.d.ts +8 -23
  12. package/cjs/liquityV2/index.js +37 -19
  13. package/cjs/moneymarket/moneymarketCommonService.js +2 -12
  14. package/cjs/portfolio/index.d.ts +16 -8
  15. package/cjs/portfolio/index.js +458 -520
  16. package/cjs/portfolio/lendingProtocols.d.ts +184 -0
  17. package/cjs/portfolio/lendingProtocols.js +196 -0
  18. package/cjs/savings/index.d.ts +8 -2
  19. package/cjs/savings/index.js +33 -4
  20. package/cjs/types/aave.d.ts +98 -2
  21. package/cjs/types/aaveV4.d.ts +44 -0
  22. package/cjs/types/common.d.ts +0 -1
  23. package/cjs/types/common.js +0 -1
  24. package/cjs/types/compound.d.ts +26 -2
  25. package/cjs/types/curveUsd.d.ts +9 -1
  26. package/cjs/types/fluid.d.ts +13 -0
  27. package/cjs/types/index.d.ts +1 -0
  28. package/cjs/types/index.js +1 -0
  29. package/cjs/types/liquity.d.ts +12 -0
  30. package/cjs/types/liquityV2.d.ts +24 -0
  31. package/cjs/types/llamaLend.d.ts +12 -1
  32. package/cjs/types/morphoBlue.d.ts +2 -0
  33. package/cjs/types/portfolio.d.ts +125 -5
  34. package/cjs/types/savings/index.d.ts +9 -1
  35. package/cjs/types/spark.d.ts +21 -1
  36. package/cjs/umbrella/index.d.ts +2 -3
  37. package/esm/aaveV3/index.d.ts +2 -12
  38. package/esm/aaveV3/sgho.d.ts +2 -16
  39. package/esm/aaveV4/lend.d.ts +2 -43
  40. package/esm/claiming/aaveV3.d.ts +2 -2
  41. package/esm/claiming/aaveV3.js +1 -1
  42. package/esm/claiming/ethena.d.ts +2 -1
  43. package/esm/claiming/king.d.ts +2 -1
  44. package/esm/claiming/spark.d.ts +2 -2
  45. package/esm/claiming/spark.js +1 -1
  46. package/esm/fluid/index.d.ts +5 -49
  47. package/esm/helpers/aaveV4Helpers/index.js +1 -11
  48. package/esm/liquity/index.d.ts +2 -12
  49. package/esm/liquityV2/index.d.ts +8 -23
  50. package/esm/liquityV2/index.js +35 -18
  51. package/esm/moneymarket/moneymarketCommonService.js +2 -12
  52. package/esm/portfolio/index.d.ts +16 -8
  53. package/esm/portfolio/index.js +458 -522
  54. package/esm/portfolio/lendingProtocols.d.ts +184 -0
  55. package/esm/portfolio/lendingProtocols.js +189 -0
  56. package/esm/savings/index.d.ts +8 -2
  57. package/esm/savings/index.js +31 -3
  58. package/esm/types/aave.d.ts +98 -2
  59. package/esm/types/aaveV4.d.ts +44 -0
  60. package/esm/types/common.d.ts +0 -1
  61. package/esm/types/common.js +0 -1
  62. package/esm/types/compound.d.ts +26 -2
  63. package/esm/types/curveUsd.d.ts +9 -1
  64. package/esm/types/fluid.d.ts +13 -0
  65. package/esm/types/index.d.ts +1 -0
  66. package/esm/types/index.js +1 -0
  67. package/esm/types/liquity.d.ts +12 -0
  68. package/esm/types/liquityV2.d.ts +24 -0
  69. package/esm/types/llamaLend.d.ts +12 -1
  70. package/esm/types/morphoBlue.d.ts +2 -0
  71. package/esm/types/portfolio.d.ts +125 -5
  72. package/esm/types/savings/index.d.ts +9 -1
  73. package/esm/types/spark.d.ts +21 -1
  74. package/esm/umbrella/index.d.ts +2 -3
  75. package/package.json +1 -1
  76. package/src/aaveV3/index.ts +2 -1
  77. package/src/aaveV3/sgho.ts +2 -17
  78. package/src/aaveV4/lend.ts +2 -48
  79. package/src/claiming/aaveV3.ts +4 -2
  80. package/src/claiming/ethena.ts +5 -5
  81. package/src/claiming/king.ts +3 -3
  82. package/src/claiming/spark.ts +6 -4
  83. package/src/fluid/index.ts +4 -3
  84. package/src/helpers/aaveV4Helpers/index.ts +1 -12
  85. package/src/liquity/index.ts +2 -2
  86. package/src/liquityV2/index.ts +48 -22
  87. package/src/moneymarket/moneymarketCommonService.ts +2 -13
  88. package/src/portfolio/index.ts +306 -331
  89. package/src/portfolio/lendingProtocols.ts +281 -0
  90. package/src/savings/index.ts +41 -4
  91. package/src/types/aave.ts +104 -1
  92. package/src/types/aaveV4.ts +49 -0
  93. package/src/types/common.ts +0 -1
  94. package/src/types/compound.ts +38 -2
  95. package/src/types/curveUsd.ts +17 -1
  96. package/src/types/fluid.ts +14 -0
  97. package/src/types/index.ts +1 -0
  98. package/src/types/liquity.ts +13 -1
  99. package/src/types/liquityV2.ts +26 -1
  100. package/src/types/llamaLend.ts +19 -1
  101. package/src/types/morphoBlue.ts +3 -0
  102. package/src/types/portfolio.ts +151 -5
  103. package/src/types/savings/index.ts +12 -1
  104. package/src/types/spark.ts +25 -1
  105. package/src/umbrella/index.ts +2 -1
@@ -27,19 +27,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.getWalletLendingSummaries = void 0;
30
+ exports.getPortfolioMarketsData = getPortfolioMarketsData;
31
+ exports.getPortfolioUserData = getPortfolioUserData;
30
32
  exports.getPortfolioData = getPortfolioData;
31
33
  exports.getShifterPortfolioData = getShifterPortfolioData;
32
34
  const decimal_js_1 = __importDefault(require("decimal.js"));
33
35
  const common_1 = require("../types/common");
34
36
  const markets_1 = require("../markets");
35
37
  const morphoBlue_1 = require("../morphoBlue");
36
- const morphoMidnight_1 = require("../morphoMidnight");
37
38
  const types_1 = require("../types");
38
39
  const compoundV3_1 = require("../compoundV3");
39
40
  const spark_1 = require("../spark");
40
41
  const curveUsd_1 = require("../curveUsd");
41
42
  const llamaLend_1 = require("../llamaLend");
42
43
  const aaveV3_1 = require("../aaveV3");
44
+ const aaveV4_1 = require("../aaveV4");
43
45
  const constants_1 = require("../constants");
44
46
  const maker_1 = require("../maker");
45
47
  const aaveV2_1 = require("../aaveV2");
@@ -53,225 +55,227 @@ const aaveV3_2 = require("../claiming/aaveV3");
53
55
  const spark_2 = require("../claiming/spark");
54
56
  const king_1 = require("../claiming/king");
55
57
  const ethena_1 = require("../claiming/ethena");
56
- const aaveV4_1 = require("../aaveV4");
57
58
  const uniswap_1 = require("../claiming/uniswap");
58
- function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1) {
59
- return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, addresses, isSim = false) {
60
- const isMainnet = network === common_1.NetworkNumber.Eth;
61
- const isFluidSupported = [common_1.NetworkNumber.Eth, common_1.NetworkNumber.Arb, common_1.NetworkNumber.Base, common_1.NetworkNumber.Plasma].includes(network);
62
- const morphoMarkets = Object.values((0, markets_1.MorphoBlueMarkets)(network)).filter((market) => market.chainIds.includes(network));
63
- const morphoMidnightMarkets = Object.values((0, markets_1.MorphoMidnightMarkets)(network)).filter((market) => market.chainIds.includes(network));
64
- const compoundV3Markets = Object.values((0, markets_1.CompoundMarkets)(network)).filter((market) => market.chainIds.includes(network) && market.value !== types_1.CompoundVersions.CompoundV2);
65
- const sparkMarkets = Object.values((0, markets_1.SparkMarkets)(network)).filter((market) => market.chainIds.includes(network));
66
- const aaveV3Markets = [types_1.AaveVersions.AaveV3, types_1.AaveVersions.AaveV3Lido, types_1.AaveVersions.AaveV3Etherfi].map((version) => (0, markets_1.AaveMarkets)(network)[version]).filter((market) => market.chainIds.includes(network));
67
- const aaveV2Markets = [types_1.AaveVersions.AaveV2].map((version) => (0, markets_1.AaveMarkets)(network)[version]).filter((market) => market.chainIds.includes(network));
68
- const compoundV2Markets = [types_1.CompoundVersions.CompoundV2].map((version) => (0, markets_1.CompoundMarkets)(network)[version]).filter((market) => market.chainIds.includes(network));
69
- const crvUsdMarkets = Object.values((0, markets_1.CrvUsdMarkets)(network)).filter((market) => market.chainIds.includes(network));
70
- const llamaLendMarkets = [common_1.NetworkNumber.Eth, common_1.NetworkNumber.Arb].includes(network) ? Object.values((0, markets_1.LlamaLendMarkets)(network)).filter((market) => market.chainIds.includes(network)) : [];
71
- const liquityV2Markets = [common_1.NetworkNumber.Eth].includes(network) ? Object.values((0, markets_1.LiquityV2Markets)(network)) : [];
72
- const liquityV2MarketsStaking = [common_1.NetworkNumber.Eth].includes(network) ? Object.values((0, markets_1.LiquityV2Markets)(network)).filter(market => !market.isLegacy) : [];
73
- const aaveV4Spokes = Object.values((0, markets_1.AaveV4Spokes)(network)).filter((market) => market.chainIds.includes(network));
74
- // batchSize is viem's cap on a batch's raw subcall calldata (bytes); the JSON-RPC body ends up
75
- // ~4x larger (hex + aggregate3 ABI + JSON overhead) and RPC providers reject bodies over
76
- // ~2.5MB with HTTP 413, so keep this small enough that no single body gets near that.
77
- // 250k gives the largest body of around 1.26MB - if we bump, we can save maybe 2-3 rpc calls but scaling takes a hit
78
- // (e.g. adding new markets may result in body size going over alchemy body size limit)
79
- const args = [network, { batch: { multicall: { batchSize: isSim ? 2000 : 250000 } } }];
80
- const client = (0, viem_1.getViemProvider)(provider, ...args);
81
- const defaultClient = (0, viem_1.getViemProvider)(defaultProvider, ...args);
82
- const morphoMarketsData = {};
83
- const morphoMidnightMarketsData = {};
84
- const compoundV3MarketsData = {};
85
- const sparkMarketsData = {};
86
- const aaveV3MarketsData = {};
87
- const makerCdps = {};
88
- const aaveV2MarketsData = {};
89
- const compoundV2MarketsData = {};
90
- const crvUsdMarketsData = {};
91
- const llamaLendMarketsData = {};
92
- const liquityV2MarketsData = {};
93
- const aaveV4SpokesData = {};
94
- const markets = {
95
- morphoMarketsData,
96
- morphoMidnightMarketsData,
97
- compoundV3MarketsData,
98
- sparkMarketsData,
99
- aaveV3MarketsData,
100
- aaveV2MarketsData,
101
- compoundV2MarketsData,
102
- crvUsdMarketsData,
103
- llamaLendMarketsData,
104
- liquityV2MarketsData,
105
- aaveV4SpokesData,
59
+ const lendingProtocols_1 = require("./lendingProtocols");
60
+ /** The markets of the protocols read by their own code below; LENDING_PROTOCOLS has the others'. */
61
+ const getPortfolioMarkets = (network) => ({
62
+ liquityV2Markets: [common_1.NetworkNumber.Eth].includes(network) ? Object.values((0, markets_1.LiquityV2Markets)(network)) : [],
63
+ liquityV2MarketsStaking: [common_1.NetworkNumber.Eth].includes(network) ? Object.values((0, markets_1.LiquityV2Markets)(network)).filter(market => !market.isLegacy) : [],
64
+ });
65
+ const getPortfolioClients = (provider, defaultProvider, network, isSim) => {
66
+ // batchSize is viem's cap on a batch's raw subcall calldata (bytes); the JSON-RPC body ends up
67
+ // ~4x larger (hex + aggregate3 ABI + JSON overhead) and RPC providers reject bodies over
68
+ // ~2.5MB with HTTP 413, so keep this small enough that no single body gets near that.
69
+ // 250k gives the largest body of around 1.26MB - if we bump, we can save maybe 2-3 rpc calls but scaling takes a hit
70
+ // (e.g. adding new markets may result in body size going over alchemy body size limit)
71
+ const args = [network, { batch: { multicall: { batchSize: isSim ? 2000 : 250000 } } }];
72
+ return {
73
+ client: (0, viem_1.getViemProvider)(provider, ...args),
74
+ defaultClient: (0, viem_1.getViemProvider)(defaultProvider, ...args),
75
+ };
76
+ };
77
+ const _getPortfolioMarketsData = (client, defaultClient, network) => __awaiter(void 0, void 0, void 0, function* () {
78
+ const { liquityV2Markets } = getPortfolioMarkets(network);
79
+ const markets = {
80
+ morphoMarketsData: {},
81
+ morphoMidnightMarketsData: {},
82
+ compoundV3MarketsData: {},
83
+ sparkMarketsData: {},
84
+ aaveV3MarketsData: {},
85
+ aaveV2MarketsData: {},
86
+ compoundV2MarketsData: {},
87
+ crvUsdMarketsData: {},
88
+ llamaLendMarketsData: {},
89
+ liquityV2MarketsData: {},
90
+ aaveV4SpokesData: {},
91
+ };
92
+ const liquityV2Failed = {};
93
+ const [lendingFailed] = yield Promise.all([
94
+ Promise.all(lendingProtocols_1.LENDING_PROTOCOLS.map((protocol) => __awaiter(void 0, void 0, void 0, function* () { return [protocol.marketsKey, yield protocol.readMarkets({ client, defaultClient, network }, markets)]; }))),
95
+ // Liquity V2's markets: its troves are read by their own code below.
96
+ ...liquityV2Markets.map((market) => __awaiter(void 0, void 0, void 0, function* () {
97
+ try {
98
+ markets.liquityV2MarketsData[market.value] = yield (0, liquityV2_1._getLiquityV2MarketData)(client, network, market);
99
+ }
100
+ catch (error) {
101
+ console.error(`Error fetching liquityV2MarketsData for market ${market.value}:`, error);
102
+ liquityV2Failed[market.value] = `Error fetching liquityV2MarketsData for market ${market.value}`;
103
+ }
104
+ })),
105
+ ]);
106
+ // A market that failed is left out of markets and named here, under its protocol's key.
107
+ const errors = {};
108
+ for (const [key, failed] of [...lendingFailed, ['liquityV2MarketsData', liquityV2Failed]]) {
109
+ if (Object.keys(failed).length)
110
+ errors[key] = failed;
111
+ }
112
+ return { markets, errors };
113
+ });
114
+ const _getPortfolioUserData = (client, network, addresses, marketsData, isSim, options) => __awaiter(void 0, void 0, void 0, function* () {
115
+ const isMainnet = network === common_1.NetworkNumber.Eth;
116
+ const includePositions = options.positions !== false;
117
+ const includeStaking = options.staking !== false;
118
+ const includeRewards = options.rewards !== false;
119
+ const includeLiquityV2 = includePositions && options.liquityV2 === true;
120
+ // The addresses positions, staking, rewards and Liquity V2 troves are read for: none when left out, so their fetches
121
+ // below make no calls.
122
+ const positionsAddresses = includePositions ? addresses : [];
123
+ const stakingAddresses = includeStaking ? addresses : [];
124
+ const rewardsAddresses = includeRewards ? addresses : [];
125
+ const liquityV2Addresses = includeLiquityV2 ? addresses : [];
126
+ const isFluidSupported = [common_1.NetworkNumber.Eth, common_1.NetworkNumber.Arb, common_1.NetworkNumber.Base, common_1.NetworkNumber.Plasma].includes(network);
127
+ const { liquityV2Markets, liquityV2MarketsStaking } = getPortfolioMarkets(network);
128
+ const positions = {};
129
+ const stakingPositions = {};
130
+ const rewardsData = {};
131
+ const makerCdpsErrors = {};
132
+ for (const address of positionsAddresses) {
133
+ positions[address.toLowerCase()] = Object.assign(Object.assign(Object.assign({}, Object.fromEntries(lendingProtocols_1.LENDING_PROTOCOLS.map((protocol) => [protocol.key, {}]))), { maker: {}, liquity: {}, fluid: {
134
+ error: '',
135
+ data: {},
136
+ } }), (includeLiquityV2 ? { liquityV2: {} } : {}));
137
+ }
138
+ // TODO: check default values, probably needed when fetching portfolio on unsupported networks
139
+ for (const address of stakingAddresses) {
140
+ stakingPositions[address.toLowerCase()] = {
141
+ aaveV3: {},
142
+ morphoBlue: {},
143
+ compoundV3: {},
144
+ spark: {},
145
+ aaveV2: {},
146
+ compoundV2: {},
147
+ liquity: {},
148
+ liquityV2: {},
149
+ fluid: {
150
+ error: '',
151
+ data: {},
152
+ },
153
+ // Set by the sBOLD/yBOLD fetch below, whether it succeeds or fails.
154
+ liquityV2SBoldYBold: { error: '', data: null },
106
155
  };
107
- const positions = {};
108
- const stakingPositions = {};
109
- const rewardsData = {};
110
- const allAddresses = [...addresses];
111
- for (const address of allAddresses) {
112
- positions[address.toLowerCase()] = {
113
- aaveV3: {},
114
- aaveV4: {},
115
- morphoBlue: {},
116
- morphoMidnight: {},
117
- compoundV3: {},
118
- spark: {},
119
- maker: {},
120
- aaveV2: {},
121
- compoundV2: {},
122
- liquity: {},
123
- crvUsd: {},
124
- llamaLend: {},
125
- fluid: {
126
- error: '',
127
- data: {},
128
- },
129
- };
130
- }
131
- // TODO: check default values, probably needed when fetching portfolio on unsupported networks
132
- for (const address of addresses) {
133
- stakingPositions[address.toLowerCase()] = {
134
- aaveV3: {},
135
- morphoBlue: {},
136
- compoundV3: {},
137
- spark: {},
138
- aaveV2: {},
139
- compoundV2: {},
140
- liquity: {},
141
- liquityV2: {},
142
- fluid: {
143
- error: '',
144
- data: {},
145
- },
146
- };
147
- rewardsData[address.toLowerCase()] = {
148
- merkl: {},
149
- aaveV3: {},
150
- spark: {},
151
- spk: {},
152
- king: {},
153
- ethena: {},
154
- };
155
- }
156
- yield Promise.allSettled([
157
- // === MARKET DATA (needs to be fetched first) ===
158
- ...morphoMarkets.map((market) => __awaiter(this, void 0, void 0, function* () {
159
- const marketData = yield (0, morphoBlue_1._getMorphoBluePortfolioMarketData)(client, network, market);
160
- morphoMarketsData[market.value] = marketData;
161
- })),
162
- ...morphoMidnightMarkets.map((market) => __awaiter(this, void 0, void 0, function* () {
163
- const marketData = yield (0, morphoMidnight_1._getMorphoMidnightMarketData)(client, network, market);
164
- morphoMidnightMarketsData[market.value] = marketData;
165
- })),
166
- ...compoundV3Markets.map((market) => __awaiter(this, void 0, void 0, function* () {
167
- const marketData = yield (0, compoundV3_1._getCompoundV3MarketsData)(client, network, market, defaultClient);
168
- compoundV3MarketsData[market.value] = marketData;
169
- })),
170
- ...sparkMarkets.map((market) => __awaiter(this, void 0, void 0, function* () {
171
- const marketData = yield (0, spark_1._getSparkMarketsData)(client, network, market);
172
- sparkMarketsData[market.value] = marketData;
173
- })),
174
- ...aaveV3Markets.map((market) => __awaiter(this, void 0, void 0, function* () {
175
- const marketData = yield (0, aaveV3_1._getAaveV3MarketData)(client, network, market);
176
- aaveV3MarketsData[market.value] = marketData;
177
- })),
178
- ...aaveV4Spokes.map((spoke) => __awaiter(this, void 0, void 0, function* () {
179
- const spokeData = yield (0, aaveV4_1._getAaveV4SpokeData)(client, network, spoke);
180
- aaveV4SpokesData[spoke.value] = spokeData;
181
- })),
182
- ...aaveV2Markets.map((market) => __awaiter(this, void 0, void 0, function* () {
183
- const marketData = yield (0, aaveV2_1._getAaveV2MarketsData)(client, network, market);
184
- aaveV2MarketsData[market.value] = marketData;
185
- })),
186
- ...compoundV2Markets.map((market) => __awaiter(this, void 0, void 0, function* () {
187
- const marketData = yield (0, compoundV2_1._getCompoundV2MarketsData)(client, network);
188
- compoundV2MarketsData[market.value] = marketData;
189
- })),
190
- ...crvUsdMarkets.map((market) => __awaiter(this, void 0, void 0, function* () {
191
- const marketData = yield (0, curveUsd_1._getCurveUsdGlobalData)(client, network, market);
192
- crvUsdMarketsData[market.value] = marketData;
193
- })),
194
- ...llamaLendMarkets.map((market) => __awaiter(this, void 0, void 0, function* () {
195
- const marketData = yield (0, llamaLend_1._getLlamaLendGlobalData)(client, network, market);
196
- llamaLendMarketsData[market.value] = marketData;
197
- })),
198
- ...liquityV2Markets.map((market) => __awaiter(this, void 0, void 0, function* () {
199
- const marketData = yield (0, liquityV2_1._getLiquityV2MarketData)(client, network, market);
200
- liquityV2MarketsData[market.value] = marketData;
201
- })),
202
- // === INDEPENDENT USER DATA (doesn't depend on market data) ===
203
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
204
- if (!isMainnet)
205
- return; // Maker CDPs are only available on mainnet
206
- const makerCdp = yield (0, maker_1._getUserCdps)(client, network, address);
207
- makerCdps[address.toLowerCase()] = makerCdp;
208
- })),
209
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
156
+ }
157
+ for (const address of rewardsAddresses) {
158
+ // merkl, spk, king and uniswap are set by their fetches below, whether they succeed or fail.
159
+ rewardsData[address.toLowerCase()] = {
160
+ merkl: { error: '', data: null },
161
+ aaveV3: {},
162
+ spark: {},
163
+ spk: { error: '', data: null },
164
+ king: { error: '', data: null },
165
+ ethena: {},
166
+ uniswap: { error: '', data: null },
167
+ };
168
+ }
169
+ // Everything starts at once; a read that needs a market's data waits for marketsData.
170
+ yield Promise.all([
171
+ // === POSITIONS THAT DO NOT NEED MARKET DATA ===
172
+ // Maker: the address's vault list, then each vault. A failed list is reported in errors.makerCdps: maker stays {},
173
+ // which would otherwise read as "no vaults".
174
+ ...positionsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
175
+ if (!isMainnet)
176
+ return; // Maker CDPs are only available on mainnet
177
+ let cdps;
178
+ try {
179
+ cdps = yield (0, maker_1._getUserCdps)(client, network, address);
180
+ }
181
+ catch (error) {
182
+ console.error(`Error fetching Maker CDPs for address ${address}:`, error);
183
+ makerCdpsErrors[address.toLowerCase()] = `Error fetching Maker CDPs for address ${address}`;
184
+ return;
185
+ }
186
+ yield Promise.all(cdps.map((cdpInfo) => __awaiter(void 0, void 0, void 0, function* () {
210
187
  try {
211
- if (!isFluidSupported)
212
- return; // Fluid is not available on Optimism
213
- const userPositions = (yield (0, fluid_1._getUserPositionsPortfolio)(client, network, address));
214
- for (const position of userPositions) {
215
- if (position.userData && new decimal_js_1.default(position.userData.suppliedUsd).gt(0)) {
216
- positions[address.toLowerCase()].fluid.data[position.userData.nftId] = position.userData;
217
- }
188
+ const cdpData = yield (0, maker_1._getMakerCdpData)(client, network, cdpInfo);
189
+ if (cdpData) {
190
+ positions[address.toLowerCase()].maker[cdpInfo.id] = { error: '', data: cdpData };
218
191
  }
219
192
  }
220
193
  catch (error) {
221
- console.error(`Error fetching Fluid positions for address ${address}:`, error);
222
- positions[address.toLowerCase()].fluid = {
223
- error: `Error fetching Fluid positions for address ${address}`,
224
- data: {},
225
- };
226
- }
227
- })),
228
- // === STAKING DATA (independent of market data) ===
229
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
230
- try {
231
- if (!isFluidSupported)
232
- return;
233
- stakingPositions[address.toLowerCase()].fluid = yield (0, fluid_1._getAllUserEarnPositionsWithFTokens)(client, network, address);
234
- }
235
- catch (error) {
236
- console.error(`Error fetching Fluid lend data for address ${address}:`, error);
237
- stakingPositions[address.toLowerCase()].fluid = { error: `Error fetching Fluid lend data for address ${address}`, data: null };
238
- }
239
- })),
240
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
241
- try {
242
- if (!isMainnet)
243
- return;
244
- stakingPositions[address.toLowerCase()].liquity = yield (0, liquity_1.getLiquityStakingData)(client, network, address);
245
- }
246
- catch (error) {
247
- console.error(`Error fetching Liquity staking data for address ${address}:`, error);
248
- stakingPositions[address.toLowerCase()].liquity = { error: `Error fetching Liquity staking data for address ${address}`, data: null };
249
- }
250
- })),
251
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
252
- try {
253
- if (!isMainnet)
254
- return;
255
- stakingPositions[address.toLowerCase()].aaveV3 = yield (0, aaveV3_1.getStakeAaveData)(client, network, address);
256
- }
257
- catch (error) {
258
- console.error(`Error fetching Aave V3 staking data for address ${address}:`, error);
259
- stakingPositions[address.toLowerCase()].aaveV3 = { error: `Error fetching Aave V3 staking data for address ${address}`, data: null };
260
- }
261
- })),
262
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
263
- try {
264
- if (!isMainnet)
265
- return;
266
- stakingPositions[address.toLowerCase()].umbrella = yield (0, umbrella_1.getUmbrellaData)(client, network, address);
194
+ console.error(`Error fetching Maker CDP data for address ${address} with ID ${cdpInfo.id}:`, error);
195
+ positions[address.toLowerCase()].maker[cdpInfo.id] = { error: `Error fetching Maker CDP data for address ${address} with ID ${cdpInfo.id}`, data: null };
267
196
  }
268
- catch (error) {
269
- console.error(`Error fetching Umbrella staking data for address ${address}:`, error);
270
- stakingPositions[address.toLowerCase()].umbrella = { error: `Error fetching Umbrella staking data for address ${address}`, data: null };
197
+ })));
198
+ })),
199
+ ...positionsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
200
+ try {
201
+ if (!isFluidSupported)
202
+ return; // Fluid is not available on Optimism
203
+ const userPositions = (yield (0, fluid_1._getUserPositionsPortfolio)(client, network, address));
204
+ for (const position of userPositions) {
205
+ if (position.userData && new decimal_js_1.default(position.userData.suppliedUsd).gt(0)) {
206
+ positions[address.toLowerCase()].fluid.data[position.userData.nftId] = position.userData;
207
+ }
271
208
  }
272
- })),
273
- // Liquity V2 staking
274
- ...liquityV2MarketsStaking.map(market => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
209
+ }
210
+ catch (error) {
211
+ console.error(`Error fetching Fluid positions for address ${address}:`, error);
212
+ positions[address.toLowerCase()].fluid = {
213
+ error: `Error fetching Fluid positions for address ${address}`,
214
+ data: {},
215
+ };
216
+ }
217
+ })),
218
+ ...positionsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
219
+ try {
220
+ if (!isMainnet)
221
+ return; // Liquity trove info is only available on mainnet
222
+ const troveInfo = yield (0, liquity_1._getLiquityTroveInfo)(client, network, address);
223
+ if (new decimal_js_1.default(troveInfo.collateral).gt(0))
224
+ positions[address.toLowerCase()].liquity = { error: '', data: troveInfo };
225
+ }
226
+ catch (error) {
227
+ console.error(`Error fetching Liquity trove info for address ${address}:`, error);
228
+ positions[address.toLowerCase()].liquity = { error: `Error fetching Liquity trove info for address ${address}`, data: null };
229
+ }
230
+ })),
231
+ // === STAKING DATA (independent of market data; Morpho Earn is with the positions below) ===
232
+ ...stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
233
+ try {
234
+ if (!isFluidSupported)
235
+ return;
236
+ stakingPositions[address.toLowerCase()].fluid = yield (0, fluid_1._getAllUserEarnPositionsWithFTokens)(client, network, address);
237
+ }
238
+ catch (error) {
239
+ console.error(`Error fetching Fluid lend data for address ${address}:`, error);
240
+ stakingPositions[address.toLowerCase()].fluid = { error: `Error fetching Fluid lend data for address ${address}`, data: null };
241
+ }
242
+ })),
243
+ ...stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
244
+ try {
245
+ if (!isMainnet)
246
+ return;
247
+ stakingPositions[address.toLowerCase()].liquity = yield (0, liquity_1.getLiquityStakingData)(client, network, address);
248
+ }
249
+ catch (error) {
250
+ console.error(`Error fetching Liquity staking data for address ${address}:`, error);
251
+ stakingPositions[address.toLowerCase()].liquity = { error: `Error fetching Liquity staking data for address ${address}`, data: null };
252
+ }
253
+ })),
254
+ ...stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
255
+ try {
256
+ if (!isMainnet)
257
+ return;
258
+ stakingPositions[address.toLowerCase()].aaveV3 = yield (0, aaveV3_1.getStakeAaveData)(client, network, address);
259
+ }
260
+ catch (error) {
261
+ console.error(`Error fetching Aave V3 staking data for address ${address}:`, error);
262
+ stakingPositions[address.toLowerCase()].aaveV3 = { error: `Error fetching Aave V3 staking data for address ${address}`, data: null };
263
+ }
264
+ })),
265
+ ...stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
266
+ try {
267
+ if (!isMainnet)
268
+ return;
269
+ stakingPositions[address.toLowerCase()].umbrella = yield (0, umbrella_1.getUmbrellaData)(client, network, address);
270
+ }
271
+ catch (error) {
272
+ console.error(`Error fetching Umbrella staking data for address ${address}:`, error);
273
+ stakingPositions[address.toLowerCase()].umbrella = { error: `Error fetching Umbrella staking data for address ${address}`, data: null };
274
+ }
275
+ })),
276
+ // Liquity V2 stability pools, then sBOLD/yBOLD, which reads them.
277
+ ...stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
278
+ yield Promise.all(liquityV2MarketsStaking.map((market) => __awaiter(void 0, void 0, void 0, function* () {
275
279
  try {
276
280
  if (!isMainnet) {
277
281
  stakingPositions[address.toLowerCase()].liquityV2[market.value] = { error: '', data: null };
@@ -284,337 +288,271 @@ function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1)
284
288
  console.error(`Error fetching Liquity V2 staking data for address ${address}, market ${market.value}:`, error);
285
289
  stakingPositions[address.toLowerCase()].liquityV2[market.value] = { error: `Error fetching Liquity V2 staking data for address ${address}`, data: null };
286
290
  }
287
- }))).flat(),
288
- // === REWARDS DATA (independent of market data) ===
289
- // Batch King rewards
290
- (() => __awaiter(this, void 0, void 0, function* () {
291
- try {
292
- if (!isMainnet) {
293
- for (const address of addresses) {
294
- rewardsData[address.toLowerCase()].king = { error: '', data: [] };
295
- }
296
- return;
297
- }
298
- const kingRewards = yield (0, king_1.getKingRewards)(client, network, addresses);
299
- for (const address of addresses) {
300
- const lowerAddress = address.toLowerCase();
301
- rewardsData[lowerAddress].king = {
302
- error: '',
303
- data: kingRewards[lowerAddress] || [],
304
- };
305
- }
291
+ })));
292
+ try {
293
+ if (!isMainnet) {
294
+ stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: '', data: null };
295
+ return;
306
296
  }
307
- catch (error) {
308
- console.error('Error fetching King rewards data in batch:', error);
309
- for (const address of addresses) {
310
- rewardsData[address.toLowerCase()].king = {
311
- error: 'Error fetching King rewards data in batch',
312
- data: null,
313
- };
297
+ const data = yield (0, liquityV2_1.getLiquitySAndYBold)(client, network, stakingPositions[address.toLowerCase()].liquityV2, address);
298
+ stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: '', data };
299
+ }
300
+ catch (error) {
301
+ console.error(`Error fetching SBold/YBold data for address ${address}:`, error);
302
+ stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: `Error fetching sBold/yBold data for address ${address}`, data: null };
303
+ }
304
+ })),
305
+ // === REWARDS DATA (independent of market data) ===
306
+ // Batch King rewards
307
+ (() => __awaiter(void 0, void 0, void 0, function* () {
308
+ try {
309
+ if (!isMainnet) {
310
+ for (const address of rewardsAddresses) {
311
+ rewardsData[address.toLowerCase()].king = { error: '', data: [] };
314
312
  }
313
+ return;
315
314
  }
316
- }))(),
317
- // Batch UNI rewards
318
- (() => __awaiter(this, void 0, void 0, function* () {
319
- try {
320
- if (!isMainnet) {
321
- for (const address of addresses) {
322
- rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
323
- }
324
- return;
325
- }
326
- const uniswapRewards = yield (0, uniswap_1.getUniswapRewards)(client, network, addresses);
327
- for (const address of addresses) {
328
- const lowerAddress = address.toLowerCase();
329
- rewardsData[lowerAddress].uniswap = {
330
- error: '',
331
- data: uniswapRewards[lowerAddress] || [],
332
- };
333
- }
315
+ const kingRewards = yield (0, king_1.getKingRewards)(client, network, rewardsAddresses);
316
+ for (const address of rewardsAddresses) {
317
+ const lowerAddress = address.toLowerCase();
318
+ rewardsData[lowerAddress].king = {
319
+ error: '',
320
+ data: kingRewards[lowerAddress] || [],
321
+ };
334
322
  }
335
- catch (error) {
336
- console.error('Error fetching Uniswap rewards data in batch:', error);
337
- for (const address of addresses) {
338
- rewardsData[address.toLowerCase()].uniswap = {
339
- error: 'Error fetching Uniswap rewards data in batch',
340
- data: null,
341
- };
342
- }
323
+ }
324
+ catch (error) {
325
+ console.error('Error fetching King rewards data in batch:', error);
326
+ for (const address of rewardsAddresses) {
327
+ rewardsData[address.toLowerCase()].king = {
328
+ error: 'Error fetching King rewards data in batch',
329
+ data: null,
330
+ };
343
331
  }
344
- }))(),
345
- ...sparkMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
346
- try {
347
- if (!isMainnet) {
348
- rewardsData[address.toLowerCase()].spark[market.value] = { error: '', data: [] };
349
- return;
332
+ }
333
+ }))(),
334
+ // Batch UNI rewards
335
+ (() => __awaiter(void 0, void 0, void 0, function* () {
336
+ try {
337
+ if (!isMainnet) {
338
+ for (const address of rewardsAddresses) {
339
+ rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
350
340
  }
351
- const sparkData = yield (0, spark_2.fetchSparkRewards)(client, network, address, market.providerAddress);
352
- rewardsData[address.toLowerCase()].spark[market.value] = { error: '', data: sparkData };
353
- }
354
- catch (error) {
355
- console.error(`Error fetching Spark rewards data for address ${address}, market ${market.value}:`, error);
356
- rewardsData[address.toLowerCase()].spark[market.value] = { error: `Error fetching Spark rewards data for address ${address}`, data: null };
357
- }
358
- }))).flat(),
359
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
360
- try {
361
- const merklData = yield (0, aaveV3_2.getMerklUnclaimedRewards)(address, network);
362
- rewardsData[address.toLowerCase()].merkl = { error: '', data: merklData };
363
- }
364
- catch (error) {
365
- console.error(`Error fetching Merkl rewards data for address ${address}:`, error);
366
- rewardsData[address.toLowerCase()].merkl = { error: `Error fetching Merkl rewards data for address ${address}`, data: null };
367
- }
368
- })),
369
- ...aaveV3Markets.map(market => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
370
- try {
371
- const aaveData = yield (0, aaveV3_2.getUnclaimedRewardsForAllMarkets)(client, network, address, market.providerAddress);
372
- rewardsData[address.toLowerCase()].aaveV3[market.value] = { error: '', data: aaveData };
373
- }
374
- catch (error) {
375
- console.error(`Error fetching Aave V3 Merit rewards data for address ${address}:`, error);
376
- rewardsData[address.toLowerCase()].aaveV3 = { error: `Error fetching Aave V3 rewards data for address ${address}`, data: null };
341
+ return;
377
342
  }
378
- }))).flat(),
379
- // Batch Spark Airdrop rewards
380
- (() => __awaiter(this, void 0, void 0, function* () {
381
- try {
382
- if (!isMainnet) {
383
- for (const address of addresses) {
384
- rewardsData[address.toLowerCase()].spk = { error: '', data: [] };
385
- }
386
- return;
387
- }
388
- const sparkAirdropRewards = yield (0, spark_2.fetchSparkAirdropRewards)(client, network, addresses);
389
- for (const address of addresses) {
390
- const lowerAddress = address.toLowerCase();
391
- rewardsData[lowerAddress].spk = {
392
- error: '',
393
- data: sparkAirdropRewards[lowerAddress] || [],
394
- };
395
- }
343
+ const uniswapRewards = yield (0, uniswap_1.getUniswapRewards)(client, network, rewardsAddresses);
344
+ for (const address of rewardsAddresses) {
345
+ const lowerAddress = address.toLowerCase();
346
+ rewardsData[lowerAddress].uniswap = {
347
+ error: '',
348
+ data: uniswapRewards[lowerAddress] || [],
349
+ };
396
350
  }
397
- catch (error) {
398
- console.error('Error fetching Spark Airdrop rewards data in batch:', error);
399
- for (const address of addresses) {
400
- rewardsData[address.toLowerCase()].spk = {
401
- error: 'Error fetching Spark Airdrop rewards data in batch',
402
- data: null,
403
- };
404
- }
351
+ }
352
+ catch (error) {
353
+ console.error('Error fetching Uniswap rewards data in batch:', error);
354
+ for (const address of rewardsAddresses) {
355
+ rewardsData[address.toLowerCase()].uniswap = {
356
+ error: 'Error fetching Uniswap rewards data in batch',
357
+ data: null,
358
+ };
405
359
  }
406
- }))(),
407
- (() => __awaiter(this, void 0, void 0, function* () {
408
- try {
409
- if (!isMainnet) {
410
- return;
411
- }
412
- const ethenaAirdropRewards = yield (0, ethena_1.fetchEthenaAirdropRewards)(addresses);
413
- for (const address of addresses) {
414
- const lowerAddress = address.toLowerCase();
415
- rewardsData[lowerAddress].ethena = {
416
- error: '',
417
- data: ethenaAirdropRewards[lowerAddress] || [],
418
- };
419
- }
360
+ }
361
+ }))(),
362
+ ...lendingProtocols_1.sparkLending.markets(network).map((market) => rewardsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
363
+ try {
364
+ if (!isMainnet) {
365
+ rewardsData[address.toLowerCase()].spark[market.value] = { error: '', data: [] };
366
+ return;
420
367
  }
421
- catch (error) {
422
- console.error('Error fetching Ethena Airdrop rewards data:', error);
423
- for (const address of addresses) {
424
- rewardsData[address.toLowerCase()].ethena = {
425
- error: 'Error fetching Ethena Airdrop rewards data in batch',
426
- data: null,
427
- };
368
+ const sparkData = yield (0, spark_2.fetchSparkRewards)(client, network, address, market.providerAddress);
369
+ rewardsData[address.toLowerCase()].spark[market.value] = { error: '', data: sparkData };
370
+ }
371
+ catch (error) {
372
+ console.error(`Error fetching Spark rewards data for address ${address}, market ${market.value}:`, error);
373
+ rewardsData[address.toLowerCase()].spark[market.value] = { error: `Error fetching Spark rewards data for address ${address}`, data: null };
374
+ }
375
+ }))).flat(),
376
+ ...rewardsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
377
+ try {
378
+ const merklData = yield (0, aaveV3_2.getMerklUnclaimedRewards)(address, network);
379
+ rewardsData[address.toLowerCase()].merkl = { error: '', data: merklData };
380
+ }
381
+ catch (error) {
382
+ console.error(`Error fetching Merkl rewards data for address ${address}:`, error);
383
+ rewardsData[address.toLowerCase()].merkl = { error: `Error fetching Merkl rewards data for address ${address}`, data: null };
384
+ }
385
+ })),
386
+ ...lendingProtocols_1.aaveV3Lending.markets(network).map(market => rewardsAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
387
+ try {
388
+ const aaveData = yield (0, aaveV3_2.getUnclaimedRewardsForAllMarkets)(client, network, address, market.providerAddress);
389
+ rewardsData[address.toLowerCase()].aaveV3[market.value] = { error: '', data: aaveData };
390
+ }
391
+ catch (error) {
392
+ console.error(`Error fetching Aave V3 Merit rewards data for address ${address}:`, error);
393
+ // This market only: the other markets keep their rewards.
394
+ rewardsData[address.toLowerCase()].aaveV3[market.value] = { error: `Error fetching Aave V3 rewards data for address ${address} on market ${market.value}`, data: null };
395
+ }
396
+ }))).flat(),
397
+ // Batch Spark Airdrop rewards
398
+ (() => __awaiter(void 0, void 0, void 0, function* () {
399
+ try {
400
+ if (!isMainnet) {
401
+ for (const address of rewardsAddresses) {
402
+ rewardsData[address.toLowerCase()].spk = { error: '', data: [] };
428
403
  }
404
+ return;
429
405
  }
430
- }))(),
431
- ]);
432
- yield Promise.all([
433
- ...aaveV3Markets.map((market) => allAddresses.map((address) => __awaiter(this, void 0, void 0, function* () {
434
- try {
435
- const accData = yield (0, aaveV3_1._getAaveV3AccountData)(client, network, address, Object.assign({ selectedMarket: market }, aaveV3MarketsData[market.value]));
436
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
437
- positions[address.toLowerCase()].aaveV3[market.value] = { error: '', data: accData };
438
- }
439
- catch (error) {
440
- console.error(`Error fetching AaveV3 account data for address ${address} on market ${market.value}:`, error);
441
- positions[address.toLowerCase()].aaveV3[market.value] = { error: `Error fetching AaveV3 account data for address ${address} on market ${market.value}`, data: null };
406
+ const sparkAirdropRewards = yield (0, spark_2.fetchSparkAirdropRewards)(client, network, rewardsAddresses);
407
+ for (const address of rewardsAddresses) {
408
+ const lowerAddress = address.toLowerCase();
409
+ rewardsData[lowerAddress].spk = {
410
+ error: '',
411
+ data: sparkAirdropRewards[lowerAddress] || [],
412
+ };
442
413
  }
443
- }))).flat(),
444
- ...aaveV4Spokes.map((spoke) => allAddresses.map((address) => __awaiter(this, void 0, void 0, function* () {
445
- try {
446
- const accData = yield (0, aaveV4_1._getAaveV4AccountData)(client, network, aaveV4SpokesData[spoke.value], address);
447
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
448
- positions[address.toLowerCase()].aaveV4[spoke.value] = { error: '', data: accData };
414
+ }
415
+ catch (error) {
416
+ console.error('Error fetching Spark Airdrop rewards data in batch:', error);
417
+ for (const address of rewardsAddresses) {
418
+ rewardsData[address.toLowerCase()].spk = {
419
+ error: 'Error fetching Spark Airdrop rewards data in batch',
420
+ data: null,
421
+ };
449
422
  }
450
- catch (error) {
451
- console.error(`Error fetching AaveV4 account data for address ${address} on spoke ${spoke.value}:`, error);
452
- positions[address.toLowerCase()].aaveV4[spoke.value] = { error: `Error fetching AaveV4 account data for address ${address} on spoke ${spoke.value}`, data: null };
423
+ }
424
+ }))(),
425
+ (() => __awaiter(void 0, void 0, void 0, function* () {
426
+ try {
427
+ if (!isMainnet) {
428
+ return;
453
429
  }
454
- }))).flat(),
455
- ...morphoMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
456
- try {
457
- const [accDataPromise, earnDataPromise] = yield Promise.allSettled([
458
- (0, morphoBlue_1._getMorphoBlueAccountData)(client, network, address, market, morphoMarketsData[market.value]),
459
- (0, morphoBlue_1.getMorphoEarn)(client, network, address, market, morphoMarketsData[market.value]),
460
- ]);
461
- if (accDataPromise.status === 'rejected') {
462
- console.error(`Error fetching MorphoBlue account data for address ${address} on market ${market.value}:`, accDataPromise.reason);
463
- positions[address.toLowerCase()].morphoBlue[market.value] = { error: `Error fetching MorphoBlue account data for address ${address} on market ${market.value}`, data: null };
464
- }
465
- if (earnDataPromise.status === 'rejected') {
466
- console.error(`Error fetching MorphoBlue account data for address ${address} on market ${market.value}:`, earnDataPromise.reason);
467
- positions[address.toLowerCase()].morphoBlue[market.value] = { error: `Error fetching MorphoBlue account data for address ${address} on market ${market.value}`, data: null };
468
- }
469
- if (accDataPromise.status !== 'rejected') {
470
- const accData = accDataPromise.value;
471
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
472
- positions[address.toLowerCase()].morphoBlue[market.value] = { error: '', data: accData };
473
- }
474
- if (earnDataPromise.status !== 'rejected') {
475
- const earnData = earnDataPromise.value;
476
- if (earnData && new decimal_js_1.default(earnData.amount).gt(0)) {
477
- stakingPositions[address.toLowerCase()].morphoBlue[market.value] = {
478
- error: '',
479
- data: earnData,
480
- };
481
- }
482
- }
430
+ const ethenaAirdropRewards = yield (0, ethena_1.fetchEthenaAirdropRewards)(rewardsAddresses);
431
+ for (const address of rewardsAddresses) {
432
+ const lowerAddress = address.toLowerCase();
433
+ rewardsData[lowerAddress].ethena = {
434
+ error: '',
435
+ data: ethenaAirdropRewards[lowerAddress] || [],
436
+ };
483
437
  }
484
- catch (error) {
485
- console.error(`Error fetching MorphoBlue account data for address ${address} on market ${market.value}:`, error);
486
- positions[address.toLowerCase()].morphoBlue[market.value] = { error: `Error fetching MorphoBlue account data for address ${address} on market ${market.value}`, data: null };
438
+ }
439
+ catch (error) {
440
+ console.error('Error fetching Ethena Airdrop rewards data:', error);
441
+ for (const address of rewardsAddresses) {
442
+ rewardsData[address.toLowerCase()].ethena = {
443
+ error: 'Error fetching Ethena Airdrop rewards data in batch',
444
+ data: null,
445
+ };
487
446
  }
488
- }))).flat(),
489
- ...morphoMidnightMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
447
+ }
448
+ }))(),
449
+ // === POSITIONS ON MARKETS (each waits for its market's data) ===
450
+ ...lendingProtocols_1.LENDING_PROTOCOLS.flatMap((protocol) => protocol.readPositions({ client, network }, positionsAddresses, marketsData, positions)),
451
+ // Morpho Blue Earn: a supply without a borrow, kept as staking, read on the same markets as Morpho Blue's positions.
452
+ ...lendingProtocols_1.morphoBlueLending.markets(network).flatMap((market) => stakingAddresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
453
+ try {
454
+ const marketData = (0, lendingProtocols_1.requireMarket)((yield marketsData).morphoMarketsData, market.value);
455
+ const earnData = yield (0, morphoBlue_1.getMorphoEarn)(client, network, address, market, marketData);
456
+ if (earnData && new decimal_js_1.default(earnData.amount).gt(0)) {
457
+ stakingPositions[address.toLowerCase()].morphoBlue[market.value] = { error: '', data: earnData };
458
+ }
459
+ }
460
+ catch (error) {
461
+ console.error(`Error fetching MorphoBlue earn data for address ${address} on market ${market.value}:`, error);
462
+ stakingPositions[address.toLowerCase()].morphoBlue[market.value] = { error: `Error fetching MorphoBlue earn data for address ${address} on market ${market.value}`, data: null };
463
+ }
464
+ }))),
465
+ // Liquity V2 troves: one market's trove ids for every address at once, then each trove's data. A failure is the
466
+ // market's error; the troves that did load stay in its data.
467
+ ...(liquityV2Addresses.length ? liquityV2Markets : []).map((market) => __awaiter(void 0, void 0, void 0, function* () {
468
+ const setEntry = (address, entry) => {
469
+ positions[address.toLowerCase()].liquityV2[market.value] = entry;
470
+ };
471
+ const failAll = (error) => liquityV2Addresses.forEach((address) => setEntry(address, { error, data: {} }));
472
+ const allMarketsData = (yield marketsData).liquityV2MarketsData;
473
+ const marketData = allMarketsData[market.value];
474
+ if (!marketData) {
475
+ failAll(`Error fetching Liquity V2 market data for market ${market.value}`);
476
+ return;
477
+ }
478
+ let troveIds;
479
+ try {
480
+ troveIds = yield (0, liquityV2_1._getLiquityV2UsersTroveIds)(client, network, market, marketData.marketData.troveNFTAddress, isSim, liquityV2Addresses);
481
+ }
482
+ catch (error) {
483
+ console.error(`Error fetching Liquity V2 trove ids on market ${market.value}:`, error);
484
+ failAll(`Error fetching Liquity V2 troves on market ${market.value}`);
485
+ return;
486
+ }
487
+ yield Promise.all(liquityV2Addresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
490
488
  var _a;
491
- try {
492
- // Markets are created lazily on the first position, so an uncreated one can hold no position.
493
- if (!((_a = morphoMidnightMarketsData[market.value]) === null || _a === void 0 ? void 0 : _a.isCreated))
494
- return;
495
- const accData = yield (0, morphoMidnight_1._getMorphoMidnightAccountData)(client, network, address, market, morphoMidnightMarketsData[market.value]);
496
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
497
- positions[address.toLowerCase()].morphoMidnight[market.value] = { error: '', data: accData };
498
- }
499
- catch (error) {
500
- console.error(`Error fetching MorphoMidnight account data for address ${address} on market ${market.value}:`, error);
501
- positions[address.toLowerCase()].morphoMidnight[market.value] = { error: `Error fetching MorphoMidnight account data for address ${address} on market ${market.value}`, data: null };
502
- }
503
- }))).flat(),
504
- ...compoundV3Markets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
505
- try {
506
- const accData = yield (0, compoundV3_1._getCompoundV3AccountData)(client, network, address, constants_1.ZERO_ADDRESS, { selectedMarket: market, assetsData: compoundV3MarketsData[market.value].assetsData });
507
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
508
- positions[address.toLowerCase()].compoundV3[market.value] = { error: '', data: accData };
509
- }
510
- catch (error) {
511
- console.error(`Error fetching CompoundV3 account data for address ${address} on market ${market.value}:`, error);
512
- positions[address.toLowerCase()].compoundV3[market.value] = { error: `Error fetching CompoundV3 account data for address ${address} on market ${market.value}`, data: null };
513
- }
514
- }))).flat(),
515
- ...sparkMarkets.map((market) => allAddresses.map((address) => __awaiter(this, void 0, void 0, function* () {
516
- try {
517
- const accData = yield (0, spark_1._getSparkAccountData)(client, network, address, { selectedMarket: market, assetsData: sparkMarketsData[market.value].assetsData, eModeCategoriesData: sparkMarketsData[market.value].eModeCategoriesData });
518
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
519
- positions[address.toLowerCase()].spark[market.value] = { error: '', data: accData };
520
- }
521
- catch (error) {
522
- console.error(`Error fetching Spark account data for address ${address} on market ${market.value}:`, error);
523
- positions[address.toLowerCase()].spark[market.value] = { error: `Error fetching Spark account data for address ${address} on market ${market.value}`, data: null };
524
- }
525
- }))).flat(),
526
- ...addresses.map((address) => (makerCdps[address.toLowerCase()] || []).map((cdpInfo) => __awaiter(this, void 0, void 0, function* () {
527
- try {
528
- const cdpData = yield (0, maker_1._getMakerCdpData)(client, network, cdpInfo);
529
- if (cdpData) {
530
- positions[address.toLowerCase()].maker[cdpInfo.id] = { error: '', data: cdpData };
489
+ const entry = { error: '', data: {} };
490
+ const failed = [];
491
+ yield Promise.all(((_a = troveIds[address]) !== null && _a !== void 0 ? _a : []).map((troveId) => __awaiter(void 0, void 0, void 0, function* () {
492
+ try {
493
+ entry.data[troveId] = yield (0, liquityV2_1._getLiquityV2TroveData)(client, network, {
494
+ selectedMarket: market,
495
+ assetsData: marketData.assetsData,
496
+ troveId,
497
+ allMarketsData: allMarketsData,
498
+ });
531
499
  }
532
- }
533
- catch (error) {
534
- console.error(`Error fetching Maker CDP data for address ${address} with ID ${cdpInfo.id}:`, error);
535
- positions[address.toLowerCase()].maker[cdpInfo.id] = { error: `Error fetching Maker CDP data for address ${address} with ID ${cdpInfo.id}`, data: null };
536
- }
537
- }))).flat(),
538
- ...aaveV2Markets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
539
- try {
540
- const accData = yield (0, aaveV2_1._getAaveV2AccountData)(client, network, address, aaveV2MarketsData[market.value].assetsData, market);
541
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
542
- positions[address.toLowerCase()].aaveV2[market.value] = { error: '', data: accData };
543
- }
544
- catch (error) {
545
- console.error(`Error fetching AaveV2 account data for address ${address}:`, error);
546
- positions[address.toLowerCase()].aaveV2[market.value] = { error: `Error fetching AaveV2 account data for address ${address}`, data: null };
547
- }
548
- }))).flat(),
549
- ...compoundV2Markets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
550
- try {
551
- const accData = yield (0, compoundV2_1._getCompoundV2AccountData)(client, network, address, compoundV2MarketsData[market.value].assetsData);
552
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0))
553
- positions[address.toLowerCase()].compoundV2[market.value] = { error: '', data: accData };
554
- }
555
- catch (error) {
556
- console.error(`Error fetching CompoundV2 account data for address ${address}:`, error);
557
- positions[address.toLowerCase()].compoundV2[market.value] = { error: `Error fetching CompoundV2 account data for address ${address}`, data: null };
558
- }
559
- }))).flat(),
560
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
561
- try {
562
- if (!isMainnet)
563
- return; // Liquity trove info is only available on mainnet
564
- const troveInfo = yield (0, liquity_1._getLiquityTroveInfo)(client, network, address);
565
- if (new decimal_js_1.default(troveInfo.collateral).gt(0))
566
- positions[address.toLowerCase()].liquity = { error: '', data: troveInfo };
567
- }
568
- catch (error) {
569
- console.error(`Error fetching Liquity trove info for address ${address}:`, error);
570
- positions[address.toLowerCase()].liquity = { error: `Error fetching Liquity trove info for address ${address}`, data: null };
571
- }
572
- })),
573
- ...crvUsdMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
574
- try {
575
- const accData = yield (0, curveUsd_1._getCurveUsdUserData)(client, network, address, market, crvUsdMarketsData[market.value].activeBand, crvUsdMarketsData[market.value].borrowRate);
576
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0) || new decimal_js_1.default(accData.borrowedUsd).gt(0)) {
577
- positions[address.toLowerCase()].crvUsd[market.value] = { error: '', data: accData };
578
- }
579
- }
580
- catch (error) {
581
- console.error(`Error fetching Curve USD account data for address ${address} on market ${market.value}:`, error);
582
- positions[address.toLowerCase()].crvUsd[market.value] = { error: `Error fetching Curve USD account data for address ${address} on market ${market.value}`, data: null };
583
- }
584
- }))).flat(),
585
- ...llamaLendMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
586
- try {
587
- const accData = yield (0, llamaLend_1._getLlamaLendUserData)(client, network, address, market, llamaLendMarketsData[market.value]);
588
- if (new decimal_js_1.default(accData.suppliedUsd).gt(0) || new decimal_js_1.default(accData.borrowedUsd).gt(0)) {
589
- positions[address.toLowerCase()].llamaLend[market.value] = { error: '', data: Object.assign(Object.assign({}, accData), { borrowRate: llamaLendMarketsData[market.value].borrowRate }) };
590
- }
591
- }
592
- catch (error) {
593
- console.error(`Error fetching LlamaLend account data for address ${address} on market ${market.value}:`, error);
594
- positions[address.toLowerCase()].llamaLend[market.value] = { error: `Error fetching LlamaLend account data for address ${address} on market ${market.value}`, data: null };
595
- }
596
- }))).flat(),
597
- // liquity sBold/yBold and staking options
598
- ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
599
- try {
600
- if (!isMainnet) {
601
- stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: '', data: null };
602
- return;
500
+ catch (error) {
501
+ console.error(`Error fetching Liquity V2 trove ${troveId} for address ${address} on market ${market.value}:`, error);
502
+ failed.push(troveId);
603
503
  }
604
- const data = yield (0, liquityV2_1.getLiquitySAndYBold)(client, network, stakingPositions[address.toLowerCase()].liquityV2, address);
605
- stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: '', data };
606
- }
607
- catch (error) {
608
- console.error(`Error fetching SBold/YBold data for address ${address}:`, error);
609
- stakingPositions[address.toLowerCase()].liquityV2SBoldYBold = { error: `Error fetching sBold/yBold data for address ${address}`, data: null };
610
- }
611
- })),
504
+ })));
505
+ if (failed.length)
506
+ entry.error = `Error fetching Liquity V2 troves ${failed.join(', ')} for address ${address} on market ${market.value}`;
507
+ setEntry(address, entry);
508
+ })));
509
+ })),
510
+ ]);
511
+ return {
512
+ positions,
513
+ stakingPositions,
514
+ rewardsData,
515
+ errors: Object.keys(makerCdpsErrors).length ? { makerCdps: makerCdpsErrors } : {},
516
+ };
517
+ });
518
+ /**
519
+ * Every market the portfolio reads on a network — the markets half of getPortfolioData, for a caller that keeps
520
+ * markets apart from what it reads per address (a cache shared by many addresses). A market that fails is left out
521
+ * of `markets` and named in `errors`.
522
+ */
523
+ function getPortfolioMarketsData(provider_1, network_1, defaultProvider_1) {
524
+ return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, isSim = false) {
525
+ const { client, defaultClient } = getPortfolioClients(provider, defaultProvider, network, isSim);
526
+ return _getPortfolioMarketsData(client, defaultClient, network);
527
+ });
528
+ }
529
+ /**
530
+ * What the portfolio reads per address — the other half of getPortfolioData — against `markets` from
531
+ * getPortfolioMarketsData. `markets` can be a promise: reads that do not need a market (Maker, Fluid, Liquity, staking,
532
+ * rewards) start at once, and each read on a market waits for it. A position on a market missing from `markets` is an
533
+ * entry with an error.
534
+ */
535
+ function getPortfolioUserData(provider_1, network_1, addresses_1, markets_2) {
536
+ return __awaiter(this, arguments, void 0, function* (provider, network, addresses, markets, isSim = false, options = {}) {
537
+ const { client } = getPortfolioClients(provider, provider, network, isSim);
538
+ return _getPortfolioUserData(client, network, addresses, Promise.resolve(markets), isSim, options);
539
+ });
540
+ }
541
+ function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1) {
542
+ return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, addresses, isSim = false, options = {}) {
543
+ // One pair of clients for both halves, so their calls batch together.
544
+ const { client, defaultClient } = getPortfolioClients(provider, defaultProvider, network, isSim);
545
+ const marketsResult = _getPortfolioMarketsData(client, defaultClient, network);
546
+ const [{ markets, errors: marketsErrors }, userData] = yield Promise.all([
547
+ marketsResult,
548
+ _getPortfolioUserData(client, network, addresses, marketsResult.then((result) => result.markets), isSim, options),
612
549
  ]);
613
550
  return {
614
- positions,
615
- stakingPositions,
616
- rewardsData,
551
+ positions: userData.positions,
552
+ stakingPositions: userData.stakingPositions,
553
+ rewardsData: userData.rewardsData,
617
554
  markets,
555
+ errors: Object.assign(Object.assign({}, (Object.keys(marketsErrors).length ? { markets: marketsErrors } : {})), userData.errors),
618
556
  };
619
557
  });
620
558
  }