@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
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Client } from 'viem';
|
|
2
|
+
import { EthAddress, NetworkNumber } from '../types/common';
|
|
3
|
+
import { AaveMarketInfo, AaveV4SpokeInfo, CompoundMarketData, CrvUSDMarketData, LlamaLendMarketData, MorphoBlueMarketData, MorphoMidnightMarketData, PortfolioMarketsData, PortfolioPositionsData, PortfolioPositionsDataForAddress, PortfolioProtocolData, SparkMarketData } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* The lending protocols the portfolio reads the same way — a market's data, then each address's position on it — one
|
|
6
|
+
* entry each. Adding such a protocol is its types (its key in PortfolioPositionsDataForAddress and in
|
|
7
|
+
* PortfolioMarketsData) and its entry in LENDING_PROTOCOLS; the portfolio reads, errors and options follow. Maker,
|
|
8
|
+
* Liquity, Fluid and Liquity V2 have shapes of their own and are read by their own code in ./index.ts.
|
|
9
|
+
*/
|
|
10
|
+
/** What a position read gets. */
|
|
11
|
+
export interface PortfolioReadContext {
|
|
12
|
+
client: Client;
|
|
13
|
+
network: NetworkNumber;
|
|
14
|
+
}
|
|
15
|
+
/** What a market read gets: also the default client, on Ethereum (Compound V3 reads its prices there). */
|
|
16
|
+
export interface PortfolioMarketsReadContext extends PortfolioReadContext {
|
|
17
|
+
defaultClient: Client;
|
|
18
|
+
}
|
|
19
|
+
type PositionKey = keyof PortfolioPositionsDataForAddress;
|
|
20
|
+
type MarketsKey = keyof PortfolioMarketsData;
|
|
21
|
+
type PositionsOf<K extends PositionKey> = NonNullable<PortfolioPositionsDataForAddress[K]>;
|
|
22
|
+
/** The data of one of a protocol's positions: what positions[address][K][market] holds as `{ error, data }`. */
|
|
23
|
+
export type LendingPositionData<K extends PositionKey> = NonNullable<PositionsOf<K>[keyof PositionsOf<K>]> extends PortfolioProtocolData<infer D> ? D : never;
|
|
24
|
+
export interface LendingProtocol<K extends PositionKey, M extends MarketsKey, Market extends {
|
|
25
|
+
value: string;
|
|
26
|
+
}> {
|
|
27
|
+
/** Its key in PortfolioMarketsData. */
|
|
28
|
+
marketsKey: M;
|
|
29
|
+
/** Its name in error messages. */
|
|
30
|
+
label: string;
|
|
31
|
+
/** Its markets on a network; none where it is not deployed. */
|
|
32
|
+
markets: (network: NetworkNumber) => Market[];
|
|
33
|
+
readMarket: (context: PortfolioMarketsReadContext, market: Market) => Promise<PortfolioMarketsData[M][string]>;
|
|
34
|
+
/** An address's position on a market; undefined when the market can hold none. */
|
|
35
|
+
readPosition: (context: PortfolioReadContext, address: EthAddress, market: Market, marketData: PortfolioMarketsData[M][string]) => Promise<LendingPositionData<K> | undefined>;
|
|
36
|
+
/** Whether there is a position to list: an address without one gets no entry for that market. */
|
|
37
|
+
holds: (position: LendingPositionData<K>) => boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A market's data, or a throw that the caller's catch turns into the position's error entry: read against a missing
|
|
41
|
+
* market, a position would otherwise come back empty and read as "no position".
|
|
42
|
+
*/
|
|
43
|
+
export declare const requireMarket: <T>(marketsData: Record<string, T>, market: string) => T;
|
|
44
|
+
export declare const aaveV3Lending: {
|
|
45
|
+
key: "aaveV3";
|
|
46
|
+
marketsKey: "aaveV3MarketsData";
|
|
47
|
+
markets: (network: NetworkNumber) => AaveMarketInfo[];
|
|
48
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
49
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
50
|
+
};
|
|
51
|
+
export declare const aaveV4Lending: {
|
|
52
|
+
key: "aaveV4";
|
|
53
|
+
marketsKey: "aaveV4SpokesData";
|
|
54
|
+
markets: (network: NetworkNumber) => AaveV4SpokeInfo[];
|
|
55
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
56
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
57
|
+
};
|
|
58
|
+
export declare const morphoBlueLending: {
|
|
59
|
+
key: "morphoBlue";
|
|
60
|
+
marketsKey: "morphoMarketsData";
|
|
61
|
+
markets: (network: NetworkNumber) => MorphoBlueMarketData[];
|
|
62
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
63
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
64
|
+
};
|
|
65
|
+
export declare const morphoMidnightLending: {
|
|
66
|
+
key: "morphoMidnight";
|
|
67
|
+
marketsKey: "morphoMidnightMarketsData";
|
|
68
|
+
markets: (network: NetworkNumber) => MorphoMidnightMarketData[];
|
|
69
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
70
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
71
|
+
};
|
|
72
|
+
export declare const compoundV3Lending: {
|
|
73
|
+
key: "compoundV3";
|
|
74
|
+
marketsKey: "compoundV3MarketsData";
|
|
75
|
+
markets: (network: NetworkNumber) => CompoundMarketData[];
|
|
76
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
77
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
78
|
+
};
|
|
79
|
+
export declare const sparkLending: {
|
|
80
|
+
key: "spark";
|
|
81
|
+
marketsKey: "sparkMarketsData";
|
|
82
|
+
markets: (network: NetworkNumber) => SparkMarketData[];
|
|
83
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
84
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
85
|
+
};
|
|
86
|
+
export declare const aaveV2Lending: {
|
|
87
|
+
key: "aaveV2";
|
|
88
|
+
marketsKey: "aaveV2MarketsData";
|
|
89
|
+
markets: (network: NetworkNumber) => AaveMarketInfo[];
|
|
90
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
91
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
92
|
+
};
|
|
93
|
+
export declare const compoundV2Lending: {
|
|
94
|
+
key: "compoundV2";
|
|
95
|
+
marketsKey: "compoundV2MarketsData";
|
|
96
|
+
markets: (network: NetworkNumber) => CompoundMarketData[];
|
|
97
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
98
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
99
|
+
};
|
|
100
|
+
export declare const crvUsdLending: {
|
|
101
|
+
key: "crvUsd";
|
|
102
|
+
marketsKey: "crvUsdMarketsData";
|
|
103
|
+
markets: (network: NetworkNumber) => CrvUSDMarketData[];
|
|
104
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
105
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
106
|
+
};
|
|
107
|
+
export declare const llamaLendLending: {
|
|
108
|
+
key: "llamaLend";
|
|
109
|
+
marketsKey: "llamaLendMarketsData";
|
|
110
|
+
markets: (network: NetworkNumber) => LlamaLendMarketData[];
|
|
111
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
112
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
113
|
+
};
|
|
114
|
+
/** Every lending protocol read through its entry, in the order positions list them. */
|
|
115
|
+
export declare const LENDING_PROTOCOLS: readonly [{
|
|
116
|
+
key: "aaveV3";
|
|
117
|
+
marketsKey: "aaveV3MarketsData";
|
|
118
|
+
markets: (network: NetworkNumber) => AaveMarketInfo[];
|
|
119
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
120
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
121
|
+
}, {
|
|
122
|
+
key: "aaveV4";
|
|
123
|
+
marketsKey: "aaveV4SpokesData";
|
|
124
|
+
markets: (network: NetworkNumber) => AaveV4SpokeInfo[];
|
|
125
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
126
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
127
|
+
}, {
|
|
128
|
+
key: "morphoBlue";
|
|
129
|
+
marketsKey: "morphoMarketsData";
|
|
130
|
+
markets: (network: NetworkNumber) => MorphoBlueMarketData[];
|
|
131
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
132
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
133
|
+
}, {
|
|
134
|
+
key: "morphoMidnight";
|
|
135
|
+
marketsKey: "morphoMidnightMarketsData";
|
|
136
|
+
markets: (network: NetworkNumber) => MorphoMidnightMarketData[];
|
|
137
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
138
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
139
|
+
}, {
|
|
140
|
+
key: "compoundV3";
|
|
141
|
+
marketsKey: "compoundV3MarketsData";
|
|
142
|
+
markets: (network: NetworkNumber) => CompoundMarketData[];
|
|
143
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
144
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
145
|
+
}, {
|
|
146
|
+
key: "spark";
|
|
147
|
+
marketsKey: "sparkMarketsData";
|
|
148
|
+
markets: (network: NetworkNumber) => SparkMarketData[];
|
|
149
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
150
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
151
|
+
}, {
|
|
152
|
+
key: "aaveV2";
|
|
153
|
+
marketsKey: "aaveV2MarketsData";
|
|
154
|
+
markets: (network: NetworkNumber) => AaveMarketInfo[];
|
|
155
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
156
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
157
|
+
}, {
|
|
158
|
+
key: "compoundV2";
|
|
159
|
+
marketsKey: "compoundV2MarketsData";
|
|
160
|
+
markets: (network: NetworkNumber) => CompoundMarketData[];
|
|
161
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
162
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
163
|
+
}, {
|
|
164
|
+
key: "crvUsd";
|
|
165
|
+
marketsKey: "crvUsdMarketsData";
|
|
166
|
+
markets: (network: NetworkNumber) => CrvUSDMarketData[];
|
|
167
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
168
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
169
|
+
}, {
|
|
170
|
+
key: "llamaLend";
|
|
171
|
+
marketsKey: "llamaLendMarketsData";
|
|
172
|
+
markets: (network: NetworkNumber) => LlamaLendMarketData[];
|
|
173
|
+
readMarkets: (context: PortfolioMarketsReadContext, markets: PortfolioMarketsData) => Promise<Record<string, string>>;
|
|
174
|
+
readPositions: (context: PortfolioReadContext, addresses: EthAddress[], marketsData: Promise<PortfolioMarketsData>, positions: PortfolioPositionsData) => Promise<void>[];
|
|
175
|
+
}];
|
|
176
|
+
export type LendingKey = typeof LENDING_PROTOCOLS[number]['key'];
|
|
177
|
+
/** The keys ./index.ts reads with code of its own. */
|
|
178
|
+
export type SpecialPositionKey = 'maker' | 'liquity' | 'fluid' | 'liquityV2';
|
|
179
|
+
type SpecialMarketsKey = 'liquityV2MarketsData';
|
|
180
|
+
type UnreadPositionKey = Exclude<PositionKey, LendingKey | SpecialPositionKey>;
|
|
181
|
+
type UnreadMarketsKey = Exclude<MarketsKey, typeof LENDING_PROTOCOLS[number]['marketsKey'] | SpecialMarketsKey>;
|
|
182
|
+
export declare const EVERY_POSITION_KEY_IS_READ: [UnreadPositionKey] extends [never] ? true : UnreadPositionKey;
|
|
183
|
+
export declare const EVERY_MARKETS_KEY_IS_READ: [UnreadMarketsKey] extends [never] ? true : UnreadMarketsKey;
|
|
184
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EVERY_MARKETS_KEY_IS_READ = exports.EVERY_POSITION_KEY_IS_READ = exports.LENDING_PROTOCOLS = exports.llamaLendLending = exports.crvUsdLending = exports.compoundV2Lending = exports.aaveV2Lending = exports.sparkLending = exports.compoundV3Lending = exports.morphoMidnightLending = exports.morphoBlueLending = exports.aaveV4Lending = exports.aaveV3Lending = exports.requireMarket = void 0;
|
|
16
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
17
|
+
const common_1 = require("../types/common");
|
|
18
|
+
const markets_1 = require("../markets");
|
|
19
|
+
const types_1 = require("../types");
|
|
20
|
+
const aaveV3_1 = require("../aaveV3");
|
|
21
|
+
const aaveV4_1 = require("../aaveV4");
|
|
22
|
+
const aaveV2_1 = require("../aaveV2");
|
|
23
|
+
const compoundV2_1 = require("../compoundV2");
|
|
24
|
+
const compoundV3_1 = require("../compoundV3");
|
|
25
|
+
const curveUsd_1 = require("../curveUsd");
|
|
26
|
+
const llamaLend_1 = require("../llamaLend");
|
|
27
|
+
const morphoBlue_1 = require("../morphoBlue");
|
|
28
|
+
const morphoMidnight_1 = require("../morphoMidnight");
|
|
29
|
+
const spark_1 = require("../spark");
|
|
30
|
+
const constants_1 = require("../constants");
|
|
31
|
+
/**
|
|
32
|
+
* A market's data, or a throw that the caller's catch turns into the position's error entry: read against a missing
|
|
33
|
+
* market, a position would otherwise come back empty and read as "no position".
|
|
34
|
+
*/
|
|
35
|
+
const requireMarket = (marketsData, market) => {
|
|
36
|
+
const marketData = marketsData[market];
|
|
37
|
+
if (!marketData)
|
|
38
|
+
throw new Error(`Market data for ${market} is not available`);
|
|
39
|
+
return marketData;
|
|
40
|
+
};
|
|
41
|
+
exports.requireMarket = requireMarket;
|
|
42
|
+
/** requireMarket for one protocol's key, typed by that key's market data. */
|
|
43
|
+
const requireMarketOf = (marketsData, key, market) => {
|
|
44
|
+
// TypeScript reads marketsData[key][market] as any protocol's market data; the key's own is what is stored there.
|
|
45
|
+
const marketData = marketsData[key][market];
|
|
46
|
+
if (!marketData)
|
|
47
|
+
throw new Error(`Market data for ${market} is not available`);
|
|
48
|
+
return marketData;
|
|
49
|
+
};
|
|
50
|
+
/** A protocol's entry with its reads, typed by its own market and position types. */
|
|
51
|
+
const lendingProtocol = (key, protocol) => {
|
|
52
|
+
/** Every market of the protocol into `markets`; resolves to the ones that failed (left out), with their errors. */
|
|
53
|
+
const readMarkets = (context, markets) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
const protocolMarkets = markets[protocol.marketsKey];
|
|
55
|
+
const failed = {};
|
|
56
|
+
yield Promise.all(protocol.markets(context.network).map((market) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
try {
|
|
58
|
+
protocolMarkets[market.value] = yield protocol.readMarket(context, market);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error(`Error fetching ${protocol.marketsKey} for market ${market.value}:`, error);
|
|
62
|
+
failed[market.value] = `Error fetching ${protocol.marketsKey} for market ${market.value}`;
|
|
63
|
+
}
|
|
64
|
+
})));
|
|
65
|
+
return failed;
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* Every address's position on every market into `positions`, each read once its market is in: an entry with the data
|
|
69
|
+
* where the address holds a position, an entry with an error where the read or its market failed, none otherwise.
|
|
70
|
+
*/
|
|
71
|
+
const readPositions = (context, addresses, marketsData, positions) => protocol.markets(context.network).flatMap((market) => addresses.map((address) => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
// Keyed by the protocol's market type in PortfolioPositionsDataForAddress; written here by market.value.
|
|
73
|
+
const byMarket = positions[address.toLowerCase()][key];
|
|
74
|
+
try {
|
|
75
|
+
const marketData = requireMarketOf(yield marketsData, protocol.marketsKey, market.value);
|
|
76
|
+
const position = yield protocol.readPosition(context, address, market, marketData);
|
|
77
|
+
if (position && protocol.holds(position))
|
|
78
|
+
byMarket[market.value] = { error: '', data: position };
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error(`Error fetching ${protocol.label} account data for address ${address} on market ${market.value}:`, error);
|
|
82
|
+
byMarket[market.value] = { error: `Error fetching ${protocol.label} account data for address ${address} on market ${market.value}`, data: null };
|
|
83
|
+
}
|
|
84
|
+
})));
|
|
85
|
+
return {
|
|
86
|
+
key, marketsKey: protocol.marketsKey, markets: protocol.markets, readMarkets, readPositions,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
const onNetwork = (network, markets) => markets.filter((market) => market.chainIds.includes(network));
|
|
90
|
+
const suppliesAnything = (position) => new decimal_js_1.default(position.suppliedUsd).gt(0);
|
|
91
|
+
const suppliesOrBorrowsAnything = (position) => new decimal_js_1.default(position.suppliedUsd).gt(0) || new decimal_js_1.default(position.borrowedUsd).gt(0);
|
|
92
|
+
exports.aaveV3Lending = lendingProtocol('aaveV3', {
|
|
93
|
+
marketsKey: 'aaveV3MarketsData',
|
|
94
|
+
label: 'AaveV3',
|
|
95
|
+
markets: (network) => onNetwork(network, [types_1.AaveVersions.AaveV3, types_1.AaveVersions.AaveV3Lido, types_1.AaveVersions.AaveV3Etherfi].map((version) => (0, markets_1.AaveMarkets)(network)[version])),
|
|
96
|
+
readMarket: ({ client, network }, market) => (0, aaveV3_1._getAaveV3MarketData)(client, network, market),
|
|
97
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, aaveV3_1._getAaveV3AccountData)(client, network, address, Object.assign({ selectedMarket: market }, marketData)),
|
|
98
|
+
holds: suppliesAnything,
|
|
99
|
+
});
|
|
100
|
+
exports.aaveV4Lending = lendingProtocol('aaveV4', {
|
|
101
|
+
marketsKey: 'aaveV4SpokesData',
|
|
102
|
+
label: 'AaveV4',
|
|
103
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.AaveV4Spokes)(network))),
|
|
104
|
+
readMarket: ({ client, network }, spoke) => (0, aaveV4_1._getAaveV4SpokeData)(client, network, spoke),
|
|
105
|
+
readPosition: ({ client, network }, address, _spoke, spokeData) => (0, aaveV4_1._getAaveV4AccountData)(client, network, spokeData, address),
|
|
106
|
+
holds: suppliesAnything,
|
|
107
|
+
});
|
|
108
|
+
exports.morphoBlueLending = lendingProtocol('morphoBlue', {
|
|
109
|
+
marketsKey: 'morphoMarketsData',
|
|
110
|
+
label: 'MorphoBlue',
|
|
111
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.MorphoBlueMarkets)(network))),
|
|
112
|
+
readMarket: ({ client, network }, market) => (0, morphoBlue_1._getMorphoBluePortfolioMarketData)(client, network, market),
|
|
113
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, morphoBlue_1._getMorphoBlueAccountData)(client, network, address, market, marketData),
|
|
114
|
+
holds: suppliesAnything,
|
|
115
|
+
});
|
|
116
|
+
exports.morphoMidnightLending = lendingProtocol('morphoMidnight', {
|
|
117
|
+
marketsKey: 'morphoMidnightMarketsData',
|
|
118
|
+
label: 'MorphoMidnight',
|
|
119
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.MorphoMidnightMarkets)(network))),
|
|
120
|
+
readMarket: ({ client, network }, market) => (0, morphoMidnight_1._getMorphoMidnightMarketData)(client, network, market),
|
|
121
|
+
// Markets are created lazily on the first position, so an uncreated one can hold no position.
|
|
122
|
+
readPosition: (_a, address_1, market_1, marketData_1) => __awaiter(void 0, [_a, address_1, market_1, marketData_1], void 0, function* ({ client, network }, address, market, marketData) {
|
|
123
|
+
return (marketData.isCreated
|
|
124
|
+
? (0, morphoMidnight_1._getMorphoMidnightAccountData)(client, network, address, market, marketData)
|
|
125
|
+
: undefined);
|
|
126
|
+
}),
|
|
127
|
+
holds: suppliesAnything,
|
|
128
|
+
});
|
|
129
|
+
exports.compoundV3Lending = lendingProtocol('compoundV3', {
|
|
130
|
+
marketsKey: 'compoundV3MarketsData',
|
|
131
|
+
label: 'CompoundV3',
|
|
132
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.CompoundMarkets)(network)).filter((market) => market.value !== types_1.CompoundVersions.CompoundV2)),
|
|
133
|
+
readMarket: ({ client, defaultClient, network }, market) => (0, compoundV3_1._getCompoundV3MarketsData)(client, network, market, defaultClient),
|
|
134
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, compoundV3_1._getCompoundV3AccountData)(client, network, address, constants_1.ZERO_ADDRESS, { selectedMarket: market, assetsData: marketData.assetsData }),
|
|
135
|
+
holds: suppliesAnything,
|
|
136
|
+
});
|
|
137
|
+
exports.sparkLending = lendingProtocol('spark', {
|
|
138
|
+
marketsKey: 'sparkMarketsData',
|
|
139
|
+
label: 'Spark',
|
|
140
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.SparkMarkets)(network))),
|
|
141
|
+
readMarket: ({ client, network }, market) => (0, spark_1._getSparkMarketsData)(client, network, market),
|
|
142
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, spark_1._getSparkAccountData)(client, network, address, {
|
|
143
|
+
selectedMarket: market, assetsData: marketData.assetsData, eModeCategoriesData: marketData.eModeCategoriesData,
|
|
144
|
+
}),
|
|
145
|
+
holds: suppliesAnything,
|
|
146
|
+
});
|
|
147
|
+
exports.aaveV2Lending = lendingProtocol('aaveV2', {
|
|
148
|
+
marketsKey: 'aaveV2MarketsData',
|
|
149
|
+
label: 'AaveV2',
|
|
150
|
+
markets: (network) => onNetwork(network, [(0, markets_1.AaveMarkets)(network)[types_1.AaveVersions.AaveV2]]),
|
|
151
|
+
readMarket: ({ client, network }, market) => (0, aaveV2_1._getAaveV2MarketsData)(client, network, market),
|
|
152
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, aaveV2_1._getAaveV2AccountData)(client, network, address, marketData.assetsData, market),
|
|
153
|
+
holds: suppliesAnything,
|
|
154
|
+
});
|
|
155
|
+
exports.compoundV2Lending = lendingProtocol('compoundV2', {
|
|
156
|
+
marketsKey: 'compoundV2MarketsData',
|
|
157
|
+
label: 'CompoundV2',
|
|
158
|
+
markets: (network) => onNetwork(network, [(0, markets_1.CompoundMarkets)(network)[types_1.CompoundVersions.CompoundV2]]),
|
|
159
|
+
readMarket: ({ client, network }) => (0, compoundV2_1._getCompoundV2MarketsData)(client, network),
|
|
160
|
+
readPosition: ({ client, network }, address, _market, marketData) => (0, compoundV2_1._getCompoundV2AccountData)(client, network, address, marketData.assetsData),
|
|
161
|
+
holds: suppliesAnything,
|
|
162
|
+
});
|
|
163
|
+
exports.crvUsdLending = lendingProtocol('crvUsd', {
|
|
164
|
+
marketsKey: 'crvUsdMarketsData',
|
|
165
|
+
label: 'Curve USD',
|
|
166
|
+
markets: (network) => onNetwork(network, Object.values((0, markets_1.CrvUsdMarkets)(network))),
|
|
167
|
+
readMarket: ({ client, network }, market) => (0, curveUsd_1._getCurveUsdGlobalData)(client, network, market),
|
|
168
|
+
// The market's borrow rate is passed in, so the read does not fetch it again.
|
|
169
|
+
readPosition: ({ client, network }, address, market, marketData) => (0, curveUsd_1._getCurveUsdUserData)(client, network, address, market, marketData.activeBand, marketData.borrowRate),
|
|
170
|
+
holds: suppliesOrBorrowsAnything,
|
|
171
|
+
});
|
|
172
|
+
exports.llamaLendLending = lendingProtocol('llamaLend', {
|
|
173
|
+
marketsKey: 'llamaLendMarketsData',
|
|
174
|
+
label: 'LlamaLend',
|
|
175
|
+
markets: (network) => ([common_1.NetworkNumber.Eth, common_1.NetworkNumber.Arb].includes(network) ? onNetwork(network, Object.values((0, markets_1.LlamaLendMarkets)(network))) : []),
|
|
176
|
+
readMarket: ({ client, network }, market) => (0, llamaLend_1._getLlamaLendGlobalData)(client, network, market),
|
|
177
|
+
readPosition: (_a, address_1, market_1, marketData_1) => __awaiter(void 0, [_a, address_1, market_1, marketData_1], void 0, function* ({ client, network }, address, market, marketData) {
|
|
178
|
+
return (Object.assign(Object.assign({}, yield (0, llamaLend_1._getLlamaLendUserData)(client, network, address, market, marketData)), { borrowRate: marketData.borrowRate }));
|
|
179
|
+
}),
|
|
180
|
+
holds: suppliesOrBorrowsAnything,
|
|
181
|
+
});
|
|
182
|
+
/** Every lending protocol read through its entry, in the order positions list them. */
|
|
183
|
+
exports.LENDING_PROTOCOLS = [
|
|
184
|
+
exports.aaveV3Lending,
|
|
185
|
+
exports.aaveV4Lending,
|
|
186
|
+
exports.morphoBlueLending,
|
|
187
|
+
exports.morphoMidnightLending,
|
|
188
|
+
exports.compoundV3Lending,
|
|
189
|
+
exports.sparkLending,
|
|
190
|
+
exports.aaveV2Lending,
|
|
191
|
+
exports.compoundV2Lending,
|
|
192
|
+
exports.crvUsdLending,
|
|
193
|
+
exports.llamaLendLending,
|
|
194
|
+
];
|
|
195
|
+
exports.EVERY_POSITION_KEY_IS_READ = true;
|
|
196
|
+
exports.EVERY_MARKETS_KEY_IS_READ = true;
|
package/cjs/savings/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SavingsData, SavingsDataWithErrors } from '../types';
|
|
2
2
|
import { EthAddress, EthereumProvider, NetworkNumber } from '../types/common';
|
|
3
3
|
import * as morphoVaults from './morphoVaults';
|
|
4
4
|
import * as yearnVaults from './yearnVaults';
|
|
@@ -8,4 +8,10 @@ import * as sparkSavingsVaults from './sparkSavingsVaults';
|
|
|
8
8
|
import * as summerVaults from './summerVaults';
|
|
9
9
|
import * as yearnV3Vaults from './yearnV3Vaults';
|
|
10
10
|
export { morphoVaults, yearnVaults, makerDsr, skyOptions, sparkSavingsVaults, summerVaults, yearnV3Vaults, };
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Every savings vault of a network for the given accounts, and, for each vault that came back without data, why — so
|
|
13
|
+
* a vault that failed is never mistaken for one the accounts have nothing in.
|
|
14
|
+
*/
|
|
15
|
+
export declare const getSavingsDataWithErrors: (provider: EthereumProvider, network: NetworkNumber, accounts: EthAddress[]) => Promise<SavingsDataWithErrors>;
|
|
16
|
+
/** Every savings vault of a network for the given accounts. A vault that failed is left out: use getSavingsDataWithErrors to tell why. */
|
|
17
|
+
export declare const getSavingsData: (provider: EthereumProvider, network: NetworkNumber, accounts: EthAddress[]) => Promise<SavingsData>;
|
package/cjs/savings/index.js
CHANGED
|
@@ -42,7 +42,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.getSavingsData = exports.yearnV3Vaults = exports.summerVaults = exports.sparkSavingsVaults = exports.skyOptions = exports.makerDsr = exports.yearnVaults = exports.morphoVaults = void 0;
|
|
45
|
+
exports.getSavingsData = exports.getSavingsDataWithErrors = exports.yearnV3Vaults = exports.summerVaults = exports.sparkSavingsVaults = exports.skyOptions = exports.makerDsr = exports.yearnVaults = exports.morphoVaults = void 0;
|
|
46
46
|
const types_1 = require("../types");
|
|
47
47
|
const common_1 = require("../types/common");
|
|
48
48
|
const morphoVaults = __importStar(require("./morphoVaults"));
|
|
@@ -59,16 +59,31 @@ const summerVaults = __importStar(require("./summerVaults"));
|
|
|
59
59
|
exports.summerVaults = summerVaults;
|
|
60
60
|
const yearnV3Vaults = __importStar(require("./yearnV3Vaults"));
|
|
61
61
|
exports.yearnV3Vaults = yearnV3Vaults;
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Every savings vault of a network for the given accounts, and, for each vault that came back without data, why — so
|
|
64
|
+
* a vault that failed is never mistaken for one the accounts have nothing in.
|
|
65
|
+
*/
|
|
66
|
+
const getSavingsDataWithErrors = (provider, network, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
const isMainnet = network === common_1.NetworkNumber.Eth;
|
|
68
|
+
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS)
|
|
69
|
+
.filter((key) => morphoVaults.morphoVaultsOptions.getMorphoVault(key).network === network);
|
|
64
70
|
const yearnVaultsList = Object.keys(yearnVaults.yearnVaultsOptions.YEARN_VAULTS);
|
|
65
71
|
const sparkSavingsVaultsList = Object.keys(sparkSavingsVaults.sparkSavingsVaultsOptions.SPARK_SAVINGS_VAULTS);
|
|
66
72
|
const yearnV3VaultsList = Object.keys(yearnV3Vaults.yearnV3VaultsOptions.YEARN_V3_VAULTS);
|
|
67
73
|
const summerVaultsList = Object.keys(summerVaults.summerVaultsOptions.SUMMER_VAULTS)
|
|
68
74
|
.filter((key) => summerVaults.summerVaultsOptions.getSummerVault(key).network === network);
|
|
75
|
+
// Every vault read on this network, so one left without data or an error can still be reported.
|
|
76
|
+
const vaultKeys = [
|
|
77
|
+
...morphoVaultsList,
|
|
78
|
+
...(isMainnet ? [
|
|
79
|
+
...yearnVaultsList, ...sparkSavingsVaultsList, ...yearnV3VaultsList, types_1.MakerDsrType.MakerDsrVault, types_1.SkySavingsType.SkySavings,
|
|
80
|
+
] : []),
|
|
81
|
+
...summerVaultsList,
|
|
82
|
+
];
|
|
69
83
|
const savingsData = {};
|
|
84
|
+
const errors = {};
|
|
70
85
|
yield Promise.all([
|
|
71
|
-
...(
|
|
86
|
+
...(morphoVaultsList.length ? [
|
|
72
87
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
88
|
try {
|
|
74
89
|
const vaults = morphoVaultsList.map((vaultKey) => morphoVaults.morphoVaultsOptions.getMorphoVault(vaultKey));
|
|
@@ -77,8 +92,11 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
77
92
|
}
|
|
78
93
|
catch (err) {
|
|
79
94
|
console.error('[getSavingsData] Error fetching morpho vaults:', err);
|
|
95
|
+
morphoVaultsList.forEach((vaultKey) => { errors[vaultKey] = `Error fetching morpho vault ${vaultKey}`; });
|
|
80
96
|
}
|
|
81
97
|
}))(),
|
|
98
|
+
] : []),
|
|
99
|
+
...(isMainnet ? [
|
|
82
100
|
...yearnVaultsList.map((vaultKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
101
|
try {
|
|
84
102
|
const vault = yearnVaults.yearnVaultsOptions.getYearnVault(vaultKey);
|
|
@@ -87,6 +105,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
87
105
|
}
|
|
88
106
|
catch (err) {
|
|
89
107
|
console.error(`[getSavingsData] Error fetching yearn vault ${vaultKey}:`, err);
|
|
108
|
+
errors[vaultKey] = `Error fetching yearn vault ${vaultKey}`;
|
|
90
109
|
}
|
|
91
110
|
})),
|
|
92
111
|
...sparkSavingsVaultsList.map((vaultKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -97,6 +116,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
97
116
|
}
|
|
98
117
|
catch (err) {
|
|
99
118
|
console.error(`[getSavingsData] Error fetching spark savings vault ${vaultKey}:`, err);
|
|
119
|
+
errors[vaultKey] = `Error fetching spark savings vault ${vaultKey}`;
|
|
100
120
|
}
|
|
101
121
|
})),
|
|
102
122
|
...yearnV3VaultsList.map((vaultKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -107,6 +127,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
107
127
|
}
|
|
108
128
|
catch (err) {
|
|
109
129
|
console.error(`[getSavingsData] Error fetching yearn v3 vault ${vaultKey}:`, err);
|
|
130
|
+
errors[vaultKey] = `Error fetching yearn v3 vault ${vaultKey}`;
|
|
110
131
|
}
|
|
111
132
|
})),
|
|
112
133
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -116,6 +137,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
116
137
|
}
|
|
117
138
|
catch (err) {
|
|
118
139
|
console.error('[getSavingsData] Error fetching maker DSR data:', err);
|
|
140
|
+
errors[types_1.MakerDsrType.MakerDsrVault] = 'Error fetching maker DSR data';
|
|
119
141
|
}
|
|
120
142
|
}))(),
|
|
121
143
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -125,6 +147,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
125
147
|
}
|
|
126
148
|
catch (err) {
|
|
127
149
|
console.error('[getSavingsData] Error fetching Sky savings data:', err);
|
|
150
|
+
errors[types_1.SkySavingsType.SkySavings] = 'Error fetching Sky savings data';
|
|
128
151
|
}
|
|
129
152
|
}))(),
|
|
130
153
|
] : []),
|
|
@@ -136,9 +159,18 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
136
159
|
}
|
|
137
160
|
catch (err) {
|
|
138
161
|
console.error(`[getSavingsData] Error fetching summer vault ${vaultKey}:`, err);
|
|
162
|
+
errors[vaultKey] = `Error fetching summer vault ${vaultKey}`;
|
|
139
163
|
}
|
|
140
164
|
})),
|
|
141
165
|
]);
|
|
142
|
-
return
|
|
166
|
+
// getMorphoVaultsData leaves out, without throwing, a vault whose on-chain reads failed or that the Morpho API did not return.
|
|
167
|
+
vaultKeys.forEach((vaultKey) => {
|
|
168
|
+
if (!savingsData[vaultKey] && !errors[vaultKey])
|
|
169
|
+
errors[vaultKey] = `No data returned for savings vault ${vaultKey}`;
|
|
170
|
+
});
|
|
171
|
+
return { data: savingsData, errors };
|
|
143
172
|
});
|
|
173
|
+
exports.getSavingsDataWithErrors = getSavingsDataWithErrors;
|
|
174
|
+
/** Every savings vault of a network for the given accounts. A vault that failed is left out: use getSavingsDataWithErrors to tell why. */
|
|
175
|
+
const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0, void 0, function* () { return (yield (0, exports.getSavingsDataWithErrors)(provider, network, accounts)).data; });
|
|
144
176
|
exports.getSavingsData = getSavingsData;
|
|
@@ -3,7 +3,7 @@ import * as morphoVaultsOptions from './options';
|
|
|
3
3
|
import { EthAddress, EthereumProvider, NetworkNumber, MorphoVault, MorphoVaultType, SavingsVaultData } from '../../types';
|
|
4
4
|
export { morphoVaultsOptions, };
|
|
5
5
|
/**
|
|
6
|
-
* Fetches liquidity for all given vaults
|
|
6
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
7
7
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
8
8
|
* absent from the map.
|
|
9
9
|
*/
|
|
@@ -53,42 +53,50 @@ const graphql_request_1 = require("graphql-request");
|
|
|
53
53
|
const tokens_1 = require("@defisaver/tokens");
|
|
54
54
|
const morphoVaultsOptions = __importStar(require("./options"));
|
|
55
55
|
exports.morphoVaultsOptions = morphoVaultsOptions;
|
|
56
|
+
const types_1 = require("../../types");
|
|
56
57
|
const viem_1 = require("../../services/viem");
|
|
57
58
|
const contracts_1 = require("../../contracts");
|
|
58
59
|
const constants_1 = require("../../constants");
|
|
59
60
|
// Morpho API caps list page size at 100 items
|
|
60
61
|
const MORPHO_API_PAGE_SIZE = 100;
|
|
61
|
-
const
|
|
62
|
+
const buildLiquidityQuery = (listField) => `
|
|
62
63
|
query VaultsLiquidity($addresses: [String!], $chainIds: [Int!]) {
|
|
63
|
-
|
|
64
|
+
${listField}(first: ${MORPHO_API_PAGE_SIZE}, where: { address_in: $addresses, chainId_in: $chainIds }) {
|
|
64
65
|
items {
|
|
65
66
|
address
|
|
66
|
-
liquidity {
|
|
67
|
-
underlying
|
|
68
|
-
}
|
|
67
|
+
liquidity${listField === 'vaults' ? ' {\n underlying\n }' : ''}
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
}`;
|
|
71
|
+
const liquidityQueries = {
|
|
72
|
+
[types_1.MorphoVaultVersion.V1]: { field: 'vaults', query: buildLiquidityQuery('vaults') },
|
|
73
|
+
[types_1.MorphoVaultVersion.V2]: { field: 'vaultV2s', query: buildLiquidityQuery('vaultV2s') },
|
|
74
|
+
};
|
|
72
75
|
/**
|
|
73
|
-
* Fetches liquidity for all given vaults
|
|
76
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
74
77
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
75
78
|
* absent from the map.
|
|
76
79
|
*/
|
|
77
80
|
const fetchMorphoVaultsLiquidity = (network, vaults) => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const requests = [];
|
|
82
|
+
[types_1.MorphoVaultVersion.V1, types_1.MorphoVaultVersion.V2].forEach((version) => {
|
|
83
|
+
const versionVaults = vaults.filter((vault) => vault.version === version);
|
|
84
|
+
for (let i = 0; i < versionVaults.length; i += MORPHO_API_PAGE_SIZE)
|
|
85
|
+
requests.push({ version, chunk: versionVaults.slice(i, i + MORPHO_API_PAGE_SIZE) });
|
|
86
|
+
});
|
|
81
87
|
const liquidityByAddress = {};
|
|
82
|
-
yield Promise.all(
|
|
83
|
-
const
|
|
88
|
+
yield Promise.all(requests.map((_a) => __awaiter(void 0, [_a], void 0, function* ({ version, chunk }) {
|
|
89
|
+
const { field, query } = liquidityQueries[version];
|
|
90
|
+
const data = yield (0, graphql_request_1.request)(constants_1.MORPHO_API_URL, query, {
|
|
84
91
|
addresses: chunk.map((vault) => vault.address),
|
|
85
92
|
chainIds: [network],
|
|
86
93
|
// the BigInt scalar serializes as a JSON number when it fits in Number.MAX_SAFE_INTEGER, a string otherwise
|
|
87
94
|
});
|
|
88
|
-
(data.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
(data[field].items || []).forEach((item) => {
|
|
96
|
+
// V1 exposes liquidity as { underlying }, V2 as a plain BigInt scalar
|
|
97
|
+
const underlying = (item === null || item === void 0 ? void 0 : item.liquidity) !== null && typeof (item === null || item === void 0 ? void 0 : item.liquidity) === 'object' ? item.liquidity.underlying : item === null || item === void 0 ? void 0 : item.liquidity;
|
|
98
|
+
if (underlying !== undefined && underlying !== null) {
|
|
99
|
+
liquidityByAddress[item.address.toLowerCase()] = String(underlying);
|
|
92
100
|
}
|
|
93
101
|
});
|
|
94
102
|
})));
|
|
@@ -102,7 +110,19 @@ const getBatchedViemProvider = (provider, network) => (0, viem_1.getViemProvider
|
|
|
102
110
|
},
|
|
103
111
|
},
|
|
104
112
|
});
|
|
105
|
-
|
|
113
|
+
// Vault V2 is ERC-4626 but has no decimals offset, so shares are converted with convertToAssets
|
|
114
|
+
const getMorphoVaultV2ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
+
const vaultContract = (0, contracts_1.getErc4626ContractViem)(provider, morphoVault.address);
|
|
116
|
+
const [totalAssets, suppliedAssets] = yield Promise.all([
|
|
117
|
+
vaultContract.read.totalAssets(),
|
|
118
|
+
Promise.all(accounts.map((account) => __awaiter(void 0, void 0, void 0, function* () {
|
|
119
|
+
const share = yield vaultContract.read.balanceOf([account]);
|
|
120
|
+
return share === BigInt(0) ? BigInt(0) : vaultContract.read.convertToAssets([share]);
|
|
121
|
+
}))),
|
|
122
|
+
]);
|
|
123
|
+
return { totalAssets, suppliedAssets };
|
|
124
|
+
});
|
|
125
|
+
const getMorphoVaultV1ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
126
|
const morphoVaultContract = (0, contracts_1.getMorphoVaultContractViem)(provider, morphoVault.address);
|
|
107
127
|
const shares = {};
|
|
108
128
|
const [totalAssets, totalSupply, decimals, decimalsOffset] = yield Promise.all([
|
|
@@ -119,11 +139,29 @@ const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(v
|
|
|
119
139
|
totalAssets, totalSupply, decimals, decimalsOffset, shares,
|
|
120
140
|
};
|
|
121
141
|
});
|
|
142
|
+
const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
return (morphoVault.version === types_1.MorphoVaultVersion.V2
|
|
144
|
+
? { v2: yield getMorphoVaultV2ChainData(provider, morphoVault, accounts) }
|
|
145
|
+
: { v1: yield getMorphoVaultV1ChainData(provider, morphoVault, accounts) });
|
|
146
|
+
});
|
|
122
147
|
const formatMorphoVaultData = (morphoVault, chainData, liquidityUnderlying, accounts) => {
|
|
123
|
-
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData;
|
|
124
|
-
const poolSize = (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset);
|
|
125
148
|
const liquidity = (0, tokens_1.assetAmountInEth)(liquidityUnderlying, morphoVault.asset);
|
|
126
149
|
const supplied = {};
|
|
150
|
+
if (chainData.v2) {
|
|
151
|
+
const { totalAssets, suppliedAssets } = chainData.v2;
|
|
152
|
+
accounts.forEach((account, i) => {
|
|
153
|
+
supplied[account.toLowerCase()] = (0, tokens_1.assetAmountInEth)(suppliedAssets[i].toString(), morphoVault.asset);
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
poolSize: (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset),
|
|
157
|
+
supplied,
|
|
158
|
+
liquidity,
|
|
159
|
+
asset: morphoVault.asset,
|
|
160
|
+
optionType: morphoVault.type,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData.v1;
|
|
164
|
+
const poolSize = (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset);
|
|
127
165
|
accounts.forEach((account) => {
|
|
128
166
|
const share = shares[account] || BigInt(0);
|
|
129
167
|
supplied[account.toLowerCase()] = new decimal_js_1.default(new decimal_js_1.default(share.toString()).mul(new decimal_js_1.default(totalAssets.toString()).add(1)).div(new decimal_js_1.default(totalSupply.toString()).add(Math.pow(10, decimalsOffset))).div(Math.pow(10, 18))
|