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