@defisaver/positions-sdk 2.1.168-stable-pair-dev → 2.1.169-custom-fetching-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/markets/morphoBlue/index.d.ts +2 -0
- package/cjs/markets/morphoBlue/index.js +18 -1
- package/cjs/portfolio/customDeFiData.d.ts +3 -0
- package/cjs/portfolio/customDeFiData.js +262 -0
- package/cjs/portfolio/index.d.ts +1 -0
- package/cjs/portfolio/index.js +15 -851
- package/cjs/types/morphoBlue.d.ts +1 -0
- package/cjs/types/morphoBlue.js +1 -0
- package/cjs/types/portfolio.d.ts +34 -0
- package/cjs/types/portfolio.js +18 -0
- package/esm/markets/morphoBlue/index.d.ts +2 -0
- package/esm/markets/morphoBlue/index.js +16 -0
- package/esm/portfolio/customDeFiData.d.ts +3 -0
- package/esm/portfolio/customDeFiData.js +256 -0
- package/esm/portfolio/index.d.ts +1 -0
- package/esm/portfolio/index.js +16 -849
- package/esm/types/morphoBlue.d.ts +1 -0
- package/esm/types/morphoBlue.js +1 -0
- package/esm/types/portfolio.d.ts +34 -0
- package/esm/types/portfolio.js +17 -1
- package/package.json +2 -2
- package/src/markets/morphoBlue/index.ts +16 -0
- package/src/portfolio/customDeFiData.ts +378 -0
- package/src/portfolio/index.ts +16 -834
- package/src/types/morphoBlue.ts +1 -0
- package/src/types/portfolio.ts +37 -0
|
@@ -110,6 +110,7 @@ export declare enum MorphoBlueVersions {
|
|
|
110
110
|
MorphoBlueUSDeUSDC_915_Base = "morphoblueusdeusdc_915_base",// USDe/USDC 0.915
|
|
111
111
|
MorphoBlueCbEthUSDC_770_Base = "morphobluecbethusdc_770_base",// cbETH/USDC 0.77
|
|
112
112
|
MorphoBlueCbXRPUSDC_625_Base = "morphobluecbxrpusdc_625_base",// cbXRP/USDC 0.625
|
|
113
|
+
MorphoBlueCbHYPEUSDC_625_Base = "morphobluecbhypeusdc_625_base",// cbHYPE/USDC 0.625
|
|
113
114
|
MorphoBlueSyrupUSDCUSDC_915_Arb = "morphobluesyrupusdcusdc_915_arb",// syrupUSDC/USDC
|
|
114
115
|
MorphoBlueWBTCUSDC_860_Arb = "morphobluewbtcusdc_860_arb",// WBTC/USDC
|
|
115
116
|
MorphoBlueWstEthUSDC_860_Arb = "morphobluewstethusdc_860_arb",// wstETH/USDC
|
package/esm/types/morphoBlue.js
CHANGED
|
@@ -117,6 +117,7 @@ export var MorphoBlueVersions;
|
|
|
117
117
|
MorphoBlueVersions["MorphoBlueUSDeUSDC_915_Base"] = "morphoblueusdeusdc_915_base";
|
|
118
118
|
MorphoBlueVersions["MorphoBlueCbEthUSDC_770_Base"] = "morphobluecbethusdc_770_base";
|
|
119
119
|
MorphoBlueVersions["MorphoBlueCbXRPUSDC_625_Base"] = "morphobluecbxrpusdc_625_base";
|
|
120
|
+
MorphoBlueVersions["MorphoBlueCbHYPEUSDC_625_Base"] = "morphobluecbhypeusdc_625_base";
|
|
120
121
|
// ARBITRUM
|
|
121
122
|
MorphoBlueVersions["MorphoBlueSyrupUSDCUSDC_915_Arb"] = "morphobluesyrupusdcusdc_915_arb";
|
|
122
123
|
MorphoBlueVersions["MorphoBlueWBTCUSDC_860_Arb"] = "morphobluewbtcusdc_860_arb";
|
package/esm/types/portfolio.d.ts
CHANGED
|
@@ -60,6 +60,40 @@ export interface PortfolioPositionsDataForAddress {
|
|
|
60
60
|
export interface PortfolioPositionsData {
|
|
61
61
|
[key: EthAddress]: PortfolioPositionsDataForAddress;
|
|
62
62
|
}
|
|
63
|
+
export declare enum PortfolioProtocol {
|
|
64
|
+
AaveV2 = "aaveV2",
|
|
65
|
+
AaveV3 = "aaveV3",
|
|
66
|
+
AaveV4 = "aaveV4",
|
|
67
|
+
CompoundV2 = "compoundV2",
|
|
68
|
+
CompoundV3 = "compoundV3",
|
|
69
|
+
Spark = "spark",
|
|
70
|
+
MorphoBlue = "morphoBlue",
|
|
71
|
+
MorphoMidnight = "morphoMidnight",
|
|
72
|
+
CrvUsd = "crvUsd",
|
|
73
|
+
LlamaLend = "llamaLend",
|
|
74
|
+
Maker = "maker",
|
|
75
|
+
Liquity = "liquity",
|
|
76
|
+
LiquityV2 = "liquityV2",
|
|
77
|
+
Fluid = "fluid"
|
|
78
|
+
}
|
|
79
|
+
export interface CustomDeFiDataOptions {
|
|
80
|
+
/** Defaults to every protocol. */
|
|
81
|
+
protocols?: PortfolioProtocol[];
|
|
82
|
+
fetchStaking?: boolean;
|
|
83
|
+
fetchRewards?: boolean;
|
|
84
|
+
/** Keep Aave V3 / Spark positions with no supply so the eMode category is available. */
|
|
85
|
+
returnEmptyEModePositions?: boolean;
|
|
86
|
+
fetchFluidMarkets?: boolean;
|
|
87
|
+
isSim?: boolean;
|
|
88
|
+
/** viem multicall calldata cap in bytes; defaults to 250k (2k when isSim). */
|
|
89
|
+
batchSize?: number;
|
|
90
|
+
}
|
|
91
|
+
export interface CustomDeFiData {
|
|
92
|
+
positions: PortfolioPositionsData;
|
|
93
|
+
stakingPositions: Record<string, any>;
|
|
94
|
+
rewardsData: Record<string, any>;
|
|
95
|
+
markets: PortfolioMarketsData;
|
|
96
|
+
}
|
|
63
97
|
export interface PortfolioMarketsData {
|
|
64
98
|
morphoMarketsData: Record<string, MorphoBlueMarketInfo>;
|
|
65
99
|
morphoMidnightMarketsData: Record<string, MorphoMidnightMarketInfo>;
|
package/esm/types/portfolio.js
CHANGED
|
@@ -1 +1,17 @@
|
|
|
1
|
-
export
|
|
1
|
+
export var PortfolioProtocol;
|
|
2
|
+
(function (PortfolioProtocol) {
|
|
3
|
+
PortfolioProtocol["AaveV2"] = "aaveV2";
|
|
4
|
+
PortfolioProtocol["AaveV3"] = "aaveV3";
|
|
5
|
+
PortfolioProtocol["AaveV4"] = "aaveV4";
|
|
6
|
+
PortfolioProtocol["CompoundV2"] = "compoundV2";
|
|
7
|
+
PortfolioProtocol["CompoundV3"] = "compoundV3";
|
|
8
|
+
PortfolioProtocol["Spark"] = "spark";
|
|
9
|
+
PortfolioProtocol["MorphoBlue"] = "morphoBlue";
|
|
10
|
+
PortfolioProtocol["MorphoMidnight"] = "morphoMidnight";
|
|
11
|
+
PortfolioProtocol["CrvUsd"] = "crvUsd";
|
|
12
|
+
PortfolioProtocol["LlamaLend"] = "llamaLend";
|
|
13
|
+
PortfolioProtocol["Maker"] = "maker";
|
|
14
|
+
PortfolioProtocol["Liquity"] = "liquity";
|
|
15
|
+
PortfolioProtocol["LiquityV2"] = "liquityV2";
|
|
16
|
+
PortfolioProtocol["Fluid"] = "fluid";
|
|
17
|
+
})(PortfolioProtocol || (PortfolioProtocol = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defisaver/positions-sdk",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.169-custom-fetching-dev",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./cjs/index.js",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"repository": "https://github.com/defisaver/defisaver-positions-sdk",
|
|
23
23
|
"license": "ISC",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@defisaver/tokens": "^1.7.
|
|
25
|
+
"@defisaver/tokens": "^1.7.50",
|
|
26
26
|
"@types/lodash": "^4.17.15",
|
|
27
27
|
"@types/memoizee": "^0.4.12",
|
|
28
28
|
"decimal.js": "^10.6.0",
|
|
@@ -1659,6 +1659,21 @@ export const MORPHO_BLUE_CBXRP_USDC_625_BASE = (networkId: NetworkNumber = Netwo
|
|
|
1659
1659
|
marketId: '0xd4a903dc6d949519060c7707f9604fdc9772c046e05c2e3a8fce0bd7196e4109',
|
|
1660
1660
|
protocolName: 'morpho-blue',
|
|
1661
1661
|
});
|
|
1662
|
+
export const MORPHO_BLUE_CBHYPE_USDC_625_BASE = (networkId: NetworkNumber = NetworkNumber.Base): MorphoBlueMarketData => ({
|
|
1663
|
+
chainIds: [NetworkNumber.Base],
|
|
1664
|
+
label: 'Morpho Blue',
|
|
1665
|
+
shortLabel: 'cbHYPE/USDC',
|
|
1666
|
+
value: MorphoBlueVersions.MorphoBlueCbHYPEUSDC_625_Base,
|
|
1667
|
+
url: 'cbhypeusdc-76629002',
|
|
1668
|
+
loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
1669
|
+
collateralToken: '0xB200000000000000000000451d033a5000cb479e',
|
|
1670
|
+
oracle: '0x7FaD8B8De2DDb7b4B415e1Aa3613e45EeF9E4bFf',
|
|
1671
|
+
oracleType: MorphoBlueOracleType.MARKET_RATE,
|
|
1672
|
+
irm: '0x46415998764C29aB2a25CbeA6254146D50D22687',
|
|
1673
|
+
lltv: 0.625,
|
|
1674
|
+
marketId: '0x76629002c9fdb20fb2092053a4f22c5c65e04a81887218b9546f2a2d82b4c0a8',
|
|
1675
|
+
protocolName: 'morpho-blue',
|
|
1676
|
+
});
|
|
1662
1677
|
|
|
1663
1678
|
// ARBITRUM
|
|
1664
1679
|
export const MORPHO_BLUE_SYRUPUSDC_USDC_915_ARB = (networkId: NetworkNumber = NetworkNumber.Eth): MorphoBlueMarketData => ({
|
|
@@ -1935,6 +1950,7 @@ export const MorphoBlueMarkets = (networkId: NetworkNumber) => ({
|
|
|
1935
1950
|
[MorphoBlueVersions.MorphoBlueUSDeUSDC_915_Base]: MORPHO_BLUE_USDE_USDC_915_BASE(networkId),
|
|
1936
1951
|
[MorphoBlueVersions.MorphoBlueCbEthUSDC_770_Base]: MORPHO_BLUE_CBETH_USDC_770_BASE(networkId),
|
|
1937
1952
|
[MorphoBlueVersions.MorphoBlueCbXRPUSDC_625_Base]: MORPHO_BLUE_CBXRP_USDC_625_BASE(networkId),
|
|
1953
|
+
[MorphoBlueVersions.MorphoBlueCbHYPEUSDC_625_Base]: MORPHO_BLUE_CBHYPE_USDC_625_BASE(networkId),
|
|
1938
1954
|
[MorphoBlueVersions.MorphoBlueWsuperOETHbWETH_915_Base]: MORPHO_BLUE_WSUPEROETHB_WETH_915_BASE(networkId),
|
|
1939
1955
|
[MorphoBlueVersions.MorphoBlueCbEthEth_945_Base]: MORPHO_BLUE_CBETH_ETH_945_BASE(networkId),
|
|
1940
1956
|
[MorphoBlueVersions.MorphoBlueCbEthEth_965_Base]: MORPHO_BLUE_CBETH_ETH_965_BASE(networkId),
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import Dec from 'decimal.js';
|
|
2
|
+
import { EthAddress, EthereumProvider, NetworkNumber } from '../types/common';
|
|
3
|
+
import {
|
|
4
|
+
AaveMarkets,
|
|
5
|
+
AaveV4Spokes,
|
|
6
|
+
CompoundMarkets,
|
|
7
|
+
CrvUsdMarkets,
|
|
8
|
+
LiquityV2Markets,
|
|
9
|
+
LlamaLendMarkets,
|
|
10
|
+
MakerActiveIlks,
|
|
11
|
+
MorphoBlueMarkets,
|
|
12
|
+
MorphoMidnightMarkets,
|
|
13
|
+
SparkMarkets,
|
|
14
|
+
} from '../markets';
|
|
15
|
+
import {
|
|
16
|
+
AaveVersions,
|
|
17
|
+
CdpInfo,
|
|
18
|
+
CompoundVersions,
|
|
19
|
+
CustomDeFiData,
|
|
20
|
+
CustomDeFiDataOptions,
|
|
21
|
+
PortfolioMarketsData,
|
|
22
|
+
PortfolioPositionsData,
|
|
23
|
+
PortfolioProtocol,
|
|
24
|
+
} from '../types';
|
|
25
|
+
import { getViemProvider } from '../services/viem';
|
|
26
|
+
import { ZERO_ADDRESS } from '../constants';
|
|
27
|
+
import { _getAaveV2AccountData, _getAaveV2MarketsData } from '../aaveV2';
|
|
28
|
+
import { _getAaveV3AccountData, _getAaveV3MarketData, getStakeAaveData } from '../aaveV3';
|
|
29
|
+
import { _getAaveV4AccountData, _getAaveV4SpokeData } from '../aaveV4';
|
|
30
|
+
import { _getCompoundV2AccountData, _getCompoundV2MarketsData } from '../compoundV2';
|
|
31
|
+
import { _getCompoundV3AccountData, _getCompoundV3MarketsData } from '../compoundV3';
|
|
32
|
+
import { _getSparkAccountData, _getSparkMarketsData } from '../spark';
|
|
33
|
+
import { _getCurveUsdGlobalData, _getCurveUsdUserData } from '../curveUsd';
|
|
34
|
+
import { _getLlamaLendGlobalData, _getLlamaLendUserData } from '../llamaLend';
|
|
35
|
+
import { _getMorphoBlueAccountData, _getMorphoBluePortfolioMarketData, getMorphoEarn } from '../morphoBlue';
|
|
36
|
+
import { _getMorphoMidnightAccountData, _getMorphoMidnightMarketData } from '../morphoMidnight';
|
|
37
|
+
import { _getMakerCdpData, _getMakerIlksData, _getUserCdps } from '../maker';
|
|
38
|
+
import { _getLiquityTroveInfo, getLiquityStakingData } from '../liquity';
|
|
39
|
+
import { _getLiquityV2MarketData, getLiquitySAndYBold, getLiquityV2Staking } from '../liquityV2';
|
|
40
|
+
import { _getAllFluidMarketDataPortfolio, _getAllUserEarnPositionsWithFTokens, _getUserPositionsPortfolio } from '../fluid';
|
|
41
|
+
import { getUmbrellaData } from '../umbrella';
|
|
42
|
+
import { getMerklUnclaimedRewards, getUnclaimedRewardsForAllMarkets } from '../claiming/aaveV3';
|
|
43
|
+
import { fetchSparkAirdropRewards, fetchSparkRewards } from '../claiming/spark';
|
|
44
|
+
import { getKingRewards } from '../claiming/king';
|
|
45
|
+
import { fetchEthenaAirdropRewards } from '../claiming/ethena';
|
|
46
|
+
import { getUniswapRewards } from '../claiming/uniswap';
|
|
47
|
+
|
|
48
|
+
const lower = (address: EthAddress) => address.toLowerCase() as EthAddress;
|
|
49
|
+
const positive = (value: string | undefined) => new Dec(value || '0').gt(0);
|
|
50
|
+
|
|
51
|
+
const supported = <T extends { chainIds: NetworkNumber[] }>(list: Record<string, T>, network: NetworkNumber) => (
|
|
52
|
+
Object.values(list).filter((m) => m.chainIds.includes(network))
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export async function getCustomDeFiData(
|
|
56
|
+
provider: EthereumProvider,
|
|
57
|
+
network: NetworkNumber,
|
|
58
|
+
defaultProvider: EthereumProvider,
|
|
59
|
+
addresses: EthAddress[],
|
|
60
|
+
options: CustomDeFiDataOptions = {},
|
|
61
|
+
): Promise<CustomDeFiData> {
|
|
62
|
+
const {
|
|
63
|
+
protocols = Object.values(PortfolioProtocol),
|
|
64
|
+
fetchStaking = false,
|
|
65
|
+
fetchRewards = false,
|
|
66
|
+
returnEmptyEModePositions = false,
|
|
67
|
+
fetchFluidMarkets = false,
|
|
68
|
+
isSim = false,
|
|
69
|
+
} = options;
|
|
70
|
+
// JSON-RPC body ends up ~4x the calldata cap; 250k keeps it under the ~2.5MB provider limit.
|
|
71
|
+
const batchSize = options.batchSize ?? (isSim ? 2_000 : 250_000);
|
|
72
|
+
const has = (protocol: PortfolioProtocol) => protocols.includes(protocol);
|
|
73
|
+
|
|
74
|
+
const isMainnet = network === NetworkNumber.Eth;
|
|
75
|
+
const isFluidSupported = [NetworkNumber.Eth, NetworkNumber.Arb, NetworkNumber.Base, NetworkNumber.Plasma].includes(network);
|
|
76
|
+
|
|
77
|
+
const client = getViemProvider(provider, network, { batch: { multicall: { batchSize } } });
|
|
78
|
+
const defaultClient = getViemProvider(defaultProvider, network, { batch: { multicall: { batchSize } } });
|
|
79
|
+
|
|
80
|
+
const aaveV3Markets = has(PortfolioProtocol.AaveV3)
|
|
81
|
+
? [AaveVersions.AaveV3, AaveVersions.AaveV3Lido, AaveVersions.AaveV3Etherfi].map((v) => AaveMarkets(network)[v]).filter((m) => m.chainIds.includes(network))
|
|
82
|
+
: [];
|
|
83
|
+
const aaveV2Markets = has(PortfolioProtocol.AaveV2) ? [AaveMarkets(network)[AaveVersions.AaveV2]].filter((m) => m.chainIds.includes(network)) : [];
|
|
84
|
+
const aaveV4Spokes = has(PortfolioProtocol.AaveV4) ? supported(AaveV4Spokes(network), network) : [];
|
|
85
|
+
const compoundV3Markets = has(PortfolioProtocol.CompoundV3) ? supported(CompoundMarkets(network), network).filter((m) => m.value !== CompoundVersions.CompoundV2) : [];
|
|
86
|
+
const compoundV2Markets = has(PortfolioProtocol.CompoundV2) ? [CompoundMarkets(network)[CompoundVersions.CompoundV2]].filter((m) => m.chainIds.includes(network)) : [];
|
|
87
|
+
const sparkMarkets = has(PortfolioProtocol.Spark) ? supported(SparkMarkets(network), network) : [];
|
|
88
|
+
const morphoMarkets = has(PortfolioProtocol.MorphoBlue) ? supported(MorphoBlueMarkets(network), network) : [];
|
|
89
|
+
const morphoMidnightMarkets = has(PortfolioProtocol.MorphoMidnight) ? supported(MorphoMidnightMarkets(network), network) : [];
|
|
90
|
+
const crvUsdMarkets = has(PortfolioProtocol.CrvUsd) ? supported(CrvUsdMarkets(network), network) : [];
|
|
91
|
+
const llamaLendMarkets = has(PortfolioProtocol.LlamaLend) && [NetworkNumber.Eth, NetworkNumber.Arb].includes(network) ? supported(LlamaLendMarkets(network), network) : [];
|
|
92
|
+
const liquityV2Markets = has(PortfolioProtocol.LiquityV2) && isMainnet ? Object.values(LiquityV2Markets(network)) : [];
|
|
93
|
+
const liquityV2StakingMarkets = liquityV2Markets.filter((m) => !m.isLegacy);
|
|
94
|
+
const fetchMaker = has(PortfolioProtocol.Maker) && isMainnet;
|
|
95
|
+
const fetchLiquity = has(PortfolioProtocol.Liquity) && isMainnet;
|
|
96
|
+
const fetchFluid = has(PortfolioProtocol.Fluid) && isFluidSupported;
|
|
97
|
+
|
|
98
|
+
const markets: PortfolioMarketsData = {
|
|
99
|
+
morphoMarketsData: {},
|
|
100
|
+
morphoMidnightMarketsData: {},
|
|
101
|
+
compoundV3MarketsData: {},
|
|
102
|
+
sparkMarketsData: {},
|
|
103
|
+
aaveV3MarketsData: {},
|
|
104
|
+
aaveV2MarketsData: {},
|
|
105
|
+
compoundV2MarketsData: {},
|
|
106
|
+
crvUsdMarketsData: {},
|
|
107
|
+
llamaLendMarketsData: {},
|
|
108
|
+
liquityV2MarketsData: {},
|
|
109
|
+
aaveV4SpokesData: {},
|
|
110
|
+
fluidMarketsData: {},
|
|
111
|
+
makerMarketsData: {},
|
|
112
|
+
};
|
|
113
|
+
const makerCdps: Record<string, CdpInfo[]> = {};
|
|
114
|
+
const positions: PortfolioPositionsData = {};
|
|
115
|
+
const stakingPositions: Record<string, any> = {};
|
|
116
|
+
const rewardsData: Record<string, any> = {};
|
|
117
|
+
|
|
118
|
+
for (const address of addresses) {
|
|
119
|
+
positions[lower(address)] = {
|
|
120
|
+
aaveV3: {},
|
|
121
|
+
aaveV4: {},
|
|
122
|
+
morphoBlue: {},
|
|
123
|
+
morphoMidnight: {},
|
|
124
|
+
compoundV3: {},
|
|
125
|
+
spark: {},
|
|
126
|
+
maker: {},
|
|
127
|
+
aaveV2: {},
|
|
128
|
+
compoundV2: {},
|
|
129
|
+
liquity: {},
|
|
130
|
+
crvUsd: {},
|
|
131
|
+
llamaLend: {},
|
|
132
|
+
fluid: { error: '', data: {} },
|
|
133
|
+
};
|
|
134
|
+
if (fetchStaking) {
|
|
135
|
+
stakingPositions[lower(address)] = {
|
|
136
|
+
aaveV3: {}, morphoBlue: {}, liquity: {}, liquityV2: {}, fluid: { error: '', data: {} },
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (fetchRewards) {
|
|
140
|
+
rewardsData[lower(address)] = {
|
|
141
|
+
merkl: {}, aaveV3: {}, spark: {}, spk: {}, king: {}, ethena: {}, uniswap: {},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const run = async <T>(label: string, fetch: () => Promise<T>, store: (data: T) => void, onError: (err: { error: string, data: null }) => void) => {
|
|
147
|
+
try {
|
|
148
|
+
store(await fetch());
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error(`Error fetching ${label}:`, error);
|
|
151
|
+
onError({ error: `Error fetching ${label}`, data: null });
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const perAddress = <M>(list: M[], task: (market: M, address: EthAddress) => Promise<void>) => list.map((m) => addresses.map((a) => task(m, a))).flat();
|
|
156
|
+
|
|
157
|
+
const batchRewards = (key: string, label: string, fetch: () => Promise<Record<string, any>>, enabled = true) => (async () => {
|
|
158
|
+
if (!enabled) {
|
|
159
|
+
for (const address of addresses) rewardsData[lower(address)][key] = { error: '', data: [] };
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const result = await fetch();
|
|
164
|
+
for (const address of addresses) rewardsData[lower(address)][key] = { error: '', data: result[lower(address)] || [] };
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error(`Error fetching ${label}:`, error);
|
|
167
|
+
for (const address of addresses) rewardsData[lower(address)][key] = { error: `Error fetching ${label}`, data: null };
|
|
168
|
+
}
|
|
169
|
+
})();
|
|
170
|
+
|
|
171
|
+
await Promise.allSettled([
|
|
172
|
+
...morphoMarkets.map(async (m) => { markets.morphoMarketsData[m.value] = await _getMorphoBluePortfolioMarketData(client, network, m); }),
|
|
173
|
+
...morphoMidnightMarkets.map(async (m) => { markets.morphoMidnightMarketsData[m.value] = await _getMorphoMidnightMarketData(client, network, m); }),
|
|
174
|
+
...compoundV3Markets.map(async (m) => { markets.compoundV3MarketsData[m.value] = await _getCompoundV3MarketsData(client, network, m, defaultClient); }),
|
|
175
|
+
...sparkMarkets.map(async (m) => { markets.sparkMarketsData[m.value] = await _getSparkMarketsData(client, network, m); }),
|
|
176
|
+
...aaveV3Markets.map(async (m) => { markets.aaveV3MarketsData[m.value] = await _getAaveV3MarketData(client, network, m); }),
|
|
177
|
+
...aaveV4Spokes.map(async (s) => { markets.aaveV4SpokesData[s.value] = await _getAaveV4SpokeData(client, network, s); }),
|
|
178
|
+
...aaveV2Markets.map(async (m) => { markets.aaveV2MarketsData[m.value] = await _getAaveV2MarketsData(client, network, m); }),
|
|
179
|
+
...compoundV2Markets.map(async (m) => { markets.compoundV2MarketsData[m.value] = await _getCompoundV2MarketsData(client, network); }),
|
|
180
|
+
...crvUsdMarkets.map(async (m) => { markets.crvUsdMarketsData[m.value] = await _getCurveUsdGlobalData(client, network, m); }),
|
|
181
|
+
...llamaLendMarkets.map(async (m) => { markets.llamaLendMarketsData[m.value] = await _getLlamaLendGlobalData(client, network, m); }),
|
|
182
|
+
...liquityV2Markets.map(async (m) => { markets.liquityV2MarketsData[m.value] = await _getLiquityV2MarketData(client, network, m); }),
|
|
183
|
+
(async () => {
|
|
184
|
+
if (!fetchFluid || !fetchFluidMarkets) return;
|
|
185
|
+
try { markets.fluidMarketsData = await _getAllFluidMarketDataPortfolio(client, network); } catch (error) { console.error('Error fetching Fluid markets data:', error); }
|
|
186
|
+
})(),
|
|
187
|
+
(async () => {
|
|
188
|
+
if (!fetchMaker) return;
|
|
189
|
+
try { markets.makerMarketsData = await _getMakerIlksData(client, network, MakerActiveIlks); } catch (error) { console.error('Error fetching Maker ilks data:', error); }
|
|
190
|
+
})(),
|
|
191
|
+
|
|
192
|
+
...addresses.map(async (address) => {
|
|
193
|
+
if (!fetchMaker) return;
|
|
194
|
+
makerCdps[lower(address)] = await _getUserCdps(client, network, address);
|
|
195
|
+
}),
|
|
196
|
+
...addresses.map((address) => fetchFluid && run(
|
|
197
|
+
`Fluid positions for address ${address}`,
|
|
198
|
+
() => _getUserPositionsPortfolio(client, network, address),
|
|
199
|
+
(userPositions) => {
|
|
200
|
+
for (const position of userPositions) {
|
|
201
|
+
if (position.userData && positive(position.userData.suppliedUsd)) positions[lower(address)].fluid.data[position.userData.nftId] = position.userData;
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
(err) => { positions[lower(address)].fluid = { error: err.error, data: {} }; },
|
|
205
|
+
)),
|
|
206
|
+
|
|
207
|
+
...(fetchStaking ? [
|
|
208
|
+
...addresses.map((address) => fetchFluid && run(
|
|
209
|
+
`Fluid lend data for address ${address}`,
|
|
210
|
+
() => _getAllUserEarnPositionsWithFTokens(client, network, address),
|
|
211
|
+
(data) => { stakingPositions[lower(address)].fluid = data; },
|
|
212
|
+
(err) => { stakingPositions[lower(address)].fluid = err; },
|
|
213
|
+
)),
|
|
214
|
+
...addresses.map((address) => fetchLiquity && run(
|
|
215
|
+
`Liquity staking data for address ${address}`,
|
|
216
|
+
() => getLiquityStakingData(client, network, address),
|
|
217
|
+
(data) => { stakingPositions[lower(address)].liquity = data; },
|
|
218
|
+
(err) => { stakingPositions[lower(address)].liquity = err; },
|
|
219
|
+
)),
|
|
220
|
+
...addresses.map((address) => has(PortfolioProtocol.AaveV3) && isMainnet && run(
|
|
221
|
+
`Aave V3 staking data for address ${address}`,
|
|
222
|
+
() => getStakeAaveData(client, network, address),
|
|
223
|
+
(data) => { stakingPositions[lower(address)].aaveV3 = data; },
|
|
224
|
+
(err) => { stakingPositions[lower(address)].aaveV3 = err; },
|
|
225
|
+
)),
|
|
226
|
+
...addresses.map((address) => has(PortfolioProtocol.AaveV3) && isMainnet && run(
|
|
227
|
+
`Umbrella staking data for address ${address}`,
|
|
228
|
+
() => getUmbrellaData(client, network, address),
|
|
229
|
+
(data) => { stakingPositions[lower(address)].umbrella = data; },
|
|
230
|
+
(err) => { stakingPositions[lower(address)].umbrella = err; },
|
|
231
|
+
)),
|
|
232
|
+
...perAddress(liquityV2StakingMarkets, (market, address) => run(
|
|
233
|
+
`Liquity V2 staking data for address ${address}, market ${market.value}`,
|
|
234
|
+
() => getLiquityV2Staking(client, network, market.value, address),
|
|
235
|
+
(data) => { stakingPositions[lower(address)].liquityV2[market.value] = { error: '', data }; },
|
|
236
|
+
(err) => { stakingPositions[lower(address)].liquityV2[market.value] = err; },
|
|
237
|
+
)),
|
|
238
|
+
] : []),
|
|
239
|
+
|
|
240
|
+
...(fetchRewards ? [
|
|
241
|
+
batchRewards('king', 'King rewards data', () => getKingRewards(client, network, addresses), isMainnet),
|
|
242
|
+
batchRewards('uniswap', 'Uniswap rewards data', () => getUniswapRewards(client, network, addresses), isMainnet),
|
|
243
|
+
batchRewards('spk', 'Spark Airdrop rewards data', () => fetchSparkAirdropRewards(client, network, addresses), isMainnet && has(PortfolioProtocol.Spark)),
|
|
244
|
+
batchRewards('ethena', 'Ethena Airdrop rewards data', () => fetchEthenaAirdropRewards(addresses), isMainnet),
|
|
245
|
+
...addresses.map((address) => run(
|
|
246
|
+
`Merkl rewards data for address ${address}`,
|
|
247
|
+
() => getMerklUnclaimedRewards(address, network),
|
|
248
|
+
(data) => { rewardsData[lower(address)].merkl = { error: '', data }; },
|
|
249
|
+
(err) => { rewardsData[lower(address)].merkl = err; },
|
|
250
|
+
)),
|
|
251
|
+
...perAddress(aaveV3Markets, (market, address) => run(
|
|
252
|
+
`Aave V3 rewards data for address ${address}, market ${market.value}`,
|
|
253
|
+
() => getUnclaimedRewardsForAllMarkets(client, network, address, market.providerAddress),
|
|
254
|
+
(data) => { rewardsData[lower(address)].aaveV3[market.value] = { error: '', data }; },
|
|
255
|
+
(err) => { rewardsData[lower(address)].aaveV3[market.value] = err; },
|
|
256
|
+
)),
|
|
257
|
+
...perAddress(sparkMarkets, (market, address) => {
|
|
258
|
+
if (!isMainnet) {
|
|
259
|
+
rewardsData[lower(address)].spark[market.value] = { error: '', data: [] };
|
|
260
|
+
return Promise.resolve();
|
|
261
|
+
}
|
|
262
|
+
return run(
|
|
263
|
+
`Spark rewards data for address ${address}, market ${market.value}`,
|
|
264
|
+
() => fetchSparkRewards(client, network, address, market.providerAddress),
|
|
265
|
+
(data) => { rewardsData[lower(address)].spark[market.value] = { error: '', data }; },
|
|
266
|
+
(err) => { rewardsData[lower(address)].spark[market.value] = err; },
|
|
267
|
+
);
|
|
268
|
+
}),
|
|
269
|
+
] : []),
|
|
270
|
+
]);
|
|
271
|
+
|
|
272
|
+
await Promise.all([
|
|
273
|
+
...perAddress(aaveV3Markets, (market, address) => run(
|
|
274
|
+
`AaveV3 account data for address ${address} on market ${market.value}`,
|
|
275
|
+
() => _getAaveV3AccountData(client, network, address, { selectedMarket: market, ...markets.aaveV3MarketsData[market.value] }),
|
|
276
|
+
(data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd)) positions[lower(address)].aaveV3[market.value] = { error: '', data }; },
|
|
277
|
+
(err) => { positions[lower(address)].aaveV3[market.value] = err; },
|
|
278
|
+
)),
|
|
279
|
+
...perAddress(sparkMarkets, (market, address) => run(
|
|
280
|
+
`Spark account data for address ${address} on market ${market.value}`,
|
|
281
|
+
() => _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: markets.sparkMarketsData[market.value].assetsData, eModeCategoriesData: markets.sparkMarketsData[market.value].eModeCategoriesData }),
|
|
282
|
+
(data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd)) positions[lower(address)].spark[market.value] = { error: '', data }; },
|
|
283
|
+
(err) => { positions[lower(address)].spark[market.value] = err; },
|
|
284
|
+
)),
|
|
285
|
+
...perAddress(aaveV4Spokes, (spoke, address) => run(
|
|
286
|
+
`AaveV4 account data for address ${address} on spoke ${spoke.value}`,
|
|
287
|
+
() => _getAaveV4AccountData(client, network, markets.aaveV4SpokesData[spoke.value], address),
|
|
288
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].aaveV4[spoke.value] = { error: '', data }; },
|
|
289
|
+
(err) => { positions[lower(address)].aaveV4[spoke.value] = err; },
|
|
290
|
+
)),
|
|
291
|
+
...perAddress(morphoMarkets, (market, address) => run(
|
|
292
|
+
`MorphoBlue account data for address ${address} on market ${market.value}`,
|
|
293
|
+
() => _getMorphoBlueAccountData(client, network, address, market, markets.morphoMarketsData[market.value]),
|
|
294
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].morphoBlue[market.value] = { error: '', data }; },
|
|
295
|
+
(err) => { positions[lower(address)].morphoBlue[market.value] = err; },
|
|
296
|
+
)),
|
|
297
|
+
...(fetchStaking ? perAddress(morphoMarkets, (market, address) => run(
|
|
298
|
+
`MorphoBlue earn data for address ${address} on market ${market.value}`,
|
|
299
|
+
() => getMorphoEarn(client, network, address, market, markets.morphoMarketsData[market.value]),
|
|
300
|
+
(data) => { if (data && positive(data.amount)) stakingPositions[lower(address)].morphoBlue[market.value] = { error: '', data }; },
|
|
301
|
+
(err) => { stakingPositions[lower(address)].morphoBlue[market.value] = err; },
|
|
302
|
+
)) : []),
|
|
303
|
+
...perAddress(morphoMidnightMarkets, (market, address) => {
|
|
304
|
+
if (!markets.morphoMidnightMarketsData[market.value]?.isCreated) return Promise.resolve();
|
|
305
|
+
return run(
|
|
306
|
+
`MorphoMidnight account data for address ${address} on market ${market.value}`,
|
|
307
|
+
() => _getMorphoMidnightAccountData(client, network, address, market, markets.morphoMidnightMarketsData[market.value]),
|
|
308
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].morphoMidnight[market.value] = { error: '', data }; },
|
|
309
|
+
(err) => { positions[lower(address)].morphoMidnight[market.value] = err; },
|
|
310
|
+
);
|
|
311
|
+
}),
|
|
312
|
+
...perAddress(compoundV3Markets, (market, address) => run(
|
|
313
|
+
`CompoundV3 account data for address ${address} on market ${market.value}`,
|
|
314
|
+
() => _getCompoundV3AccountData(client, network, address, ZERO_ADDRESS, { selectedMarket: market, assetsData: markets.compoundV3MarketsData[market.value].assetsData }),
|
|
315
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].compoundV3[market.value] = { error: '', data }; },
|
|
316
|
+
(err) => { positions[lower(address)].compoundV3[market.value] = err; },
|
|
317
|
+
)),
|
|
318
|
+
...perAddress(compoundV2Markets, (market, address) => run(
|
|
319
|
+
`CompoundV2 account data for address ${address}`,
|
|
320
|
+
() => _getCompoundV2AccountData(client, network, address, markets.compoundV2MarketsData[market.value].assetsData),
|
|
321
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].compoundV2[market.value] = { error: '', data }; },
|
|
322
|
+
(err) => { positions[lower(address)].compoundV2[market.value] = err; },
|
|
323
|
+
)),
|
|
324
|
+
...perAddress(aaveV2Markets, (market, address) => run(
|
|
325
|
+
`AaveV2 account data for address ${address}`,
|
|
326
|
+
() => _getAaveV2AccountData(client, network, address, markets.aaveV2MarketsData[market.value].assetsData, market),
|
|
327
|
+
(data) => { if (positive(data.suppliedUsd)) positions[lower(address)].aaveV2[market.value] = { error: '', data }; },
|
|
328
|
+
(err) => { positions[lower(address)].aaveV2[market.value] = err; },
|
|
329
|
+
)),
|
|
330
|
+
...perAddress(crvUsdMarkets, (market, address) => run(
|
|
331
|
+
`Curve USD account data for address ${address} on market ${market.value}`,
|
|
332
|
+
() => _getCurveUsdUserData(client, network, address, market, markets.crvUsdMarketsData[market.value].activeBand, markets.crvUsdMarketsData[market.value].borrowRate),
|
|
333
|
+
(data) => { if (positive(data.suppliedUsd) || positive(data.borrowedUsd)) positions[lower(address)].crvUsd[market.value] = { error: '', data }; },
|
|
334
|
+
(err) => { positions[lower(address)].crvUsd[market.value] = err; },
|
|
335
|
+
)),
|
|
336
|
+
...perAddress(llamaLendMarkets, (market, address) => run(
|
|
337
|
+
`LlamaLend account data for address ${address} on market ${market.value}`,
|
|
338
|
+
() => _getLlamaLendUserData(client, network, address, market, markets.llamaLendMarketsData[market.value]),
|
|
339
|
+
(data) => {
|
|
340
|
+
if (positive(data.suppliedUsd) || positive(data.borrowedUsd)) {
|
|
341
|
+
positions[lower(address)].llamaLend[market.value] = { error: '', data: { ...data, borrowRate: markets.llamaLendMarketsData[market.value].borrowRate } };
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
(err) => { positions[lower(address)].llamaLend[market.value] = err; },
|
|
345
|
+
)),
|
|
346
|
+
...addresses.map((address) => (makerCdps[lower(address)] || []).map((cdpInfo) => run(
|
|
347
|
+
`Maker CDP data for address ${address} with ID ${cdpInfo.id}`,
|
|
348
|
+
() => _getMakerCdpData(client, network, cdpInfo, markets.makerMarketsData[cdpInfo.ilkLabel]),
|
|
349
|
+
(data) => { if (data) positions[lower(address)].maker[cdpInfo.id] = { error: '', data }; },
|
|
350
|
+
(err) => { positions[lower(address)].maker[cdpInfo.id] = err; },
|
|
351
|
+
))).flat(),
|
|
352
|
+
...addresses.map((address) => fetchLiquity && run(
|
|
353
|
+
`Liquity trove info for address ${address}`,
|
|
354
|
+
() => _getLiquityTroveInfo(client, network, address),
|
|
355
|
+
(data) => { if (positive(data.collateral)) positions[lower(address)].liquity = { error: '', data }; },
|
|
356
|
+
(err) => { positions[lower(address)].liquity = err; },
|
|
357
|
+
)),
|
|
358
|
+
...(fetchStaking && has(PortfolioProtocol.LiquityV2) ? addresses.map((address) => {
|
|
359
|
+
if (!isMainnet) {
|
|
360
|
+
stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data: null };
|
|
361
|
+
return Promise.resolve();
|
|
362
|
+
}
|
|
363
|
+
return run(
|
|
364
|
+
`sBold/yBold data for address ${address}`,
|
|
365
|
+
() => getLiquitySAndYBold(client, network, stakingPositions[lower(address)].liquityV2, address),
|
|
366
|
+
(data) => { stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data }; },
|
|
367
|
+
(err) => { stakingPositions[lower(address)].liquityV2SBoldYBold = err; },
|
|
368
|
+
);
|
|
369
|
+
}) : []),
|
|
370
|
+
]);
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
positions,
|
|
374
|
+
stakingPositions,
|
|
375
|
+
rewardsData,
|
|
376
|
+
markets,
|
|
377
|
+
};
|
|
378
|
+
}
|