@moonwell-fi/moonwell-sdk 0.22.0 → 0.24.0
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/CHANGELOG.md +28 -0
- package/_cjs/actions/axiosWithRetry.js +10 -11
- package/_cjs/actions/axiosWithRetry.js.map +1 -1
- package/_cjs/actions/core/getUserBalances.js +11 -24
- package/_cjs/actions/core/getUserBalances.js.map +1 -1
- package/_cjs/actions/core/markets/common.js +30 -35
- package/_cjs/actions/core/markets/common.js.map +1 -1
- package/_cjs/actions/core/markets/getMarkets.js +7 -3
- package/_cjs/actions/core/markets/getMarkets.js.map +1 -1
- package/_cjs/actions/core/user-positions/common.js +56 -60
- package/_cjs/actions/core/user-positions/common.js.map +1 -1
- package/_cjs/actions/core/user-positions/getUserPositions.js +9 -6
- package/_cjs/actions/core/user-positions/getUserPositions.js.map +1 -1
- package/_cjs/actions/governance/proposals/common.js +0 -5
- package/_cjs/actions/governance/proposals/common.js.map +1 -1
- package/_cjs/actions/index.js +3 -1
- package/_cjs/actions/index.js.map +1 -1
- package/_cjs/actions/morpho/markets/common.js +128 -26
- package/_cjs/actions/morpho/markets/common.js.map +1 -1
- package/_cjs/actions/morpho/markets/getMorphoMarket.js +1 -0
- package/_cjs/actions/morpho/markets/getMorphoMarket.js.map +1 -1
- package/_cjs/actions/morpho/markets/getMorphoMarkets.js +1 -0
- package/_cjs/actions/morpho/markets/getMorphoMarkets.js.map +1 -1
- package/_cjs/actions/morpho/markets/getMorphoMarketsSharedLiquidity.js +46 -0
- package/_cjs/actions/morpho/markets/getMorphoMarketsSharedLiquidity.js.map +1 -0
- package/_cjs/actions/morpho/user-positions/common.js +26 -24
- package/_cjs/actions/morpho/user-positions/common.js.map +1 -1
- package/_cjs/actions/morpho/user-positions/getMorphoMarketUserPositions.js +7 -8
- package/_cjs/actions/morpho/user-positions/getMorphoMarketUserPositions.js.map +1 -1
- package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositions.js +7 -8
- package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositions.js.map +1 -1
- package/_cjs/actions/retry.js +43 -13
- package/_cjs/actions/retry.js.map +1 -1
- package/_cjs/client/createActions.js +2 -0
- package/_cjs/client/createActions.js.map +1 -1
- package/_cjs/client/createMoonwellClient.js.map +1 -1
- package/_cjs/common/error.js +37 -1
- package/_cjs/common/error.js.map +1 -1
- package/_cjs/common/index.js +2 -1
- package/_cjs/common/index.js.map +1 -1
- package/_cjs/common/readAcrossEnvironments.js +17 -0
- package/_cjs/common/readAcrossEnvironments.js.map +1 -0
- package/_cjs/environments/index.js.map +1 -1
- package/_cjs/environments/types/config.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/index.js +3 -1
- package/_cjs/index.js.map +1 -1
- package/_esm/actions/axiosWithRetry.js +11 -13
- package/_esm/actions/axiosWithRetry.js.map +1 -1
- package/_esm/actions/core/getUserBalances.js +23 -24
- package/_esm/actions/core/getUserBalances.js.map +1 -1
- package/_esm/actions/core/markets/common.js +34 -35
- package/_esm/actions/core/markets/common.js.map +1 -1
- package/_esm/actions/core/markets/getMarkets.js +7 -3
- package/_esm/actions/core/markets/getMarkets.js.map +1 -1
- package/_esm/actions/core/user-positions/common.js +65 -63
- package/_esm/actions/core/user-positions/common.js.map +1 -1
- package/_esm/actions/core/user-positions/getUserPositions.js +14 -6
- package/_esm/actions/core/user-positions/getUserPositions.js.map +1 -1
- package/_esm/actions/governance/proposals/common.js +0 -2
- package/_esm/actions/governance/proposals/common.js.map +1 -1
- package/_esm/actions/index.js +1 -0
- package/_esm/actions/index.js.map +1 -1
- package/_esm/actions/morpho/markets/common.js +136 -27
- package/_esm/actions/morpho/markets/common.js.map +1 -1
- package/_esm/actions/morpho/markets/getMorphoMarket.js +1 -0
- package/_esm/actions/morpho/markets/getMorphoMarket.js.map +1 -1
- package/_esm/actions/morpho/markets/getMorphoMarkets.js +1 -0
- package/_esm/actions/morpho/markets/getMorphoMarkets.js.map +1 -1
- package/_esm/actions/morpho/markets/getMorphoMarketsSharedLiquidity.js +48 -0
- package/_esm/actions/morpho/markets/getMorphoMarketsSharedLiquidity.js.map +1 -0
- package/_esm/actions/morpho/user-positions/common.js +31 -24
- package/_esm/actions/morpho/user-positions/common.js.map +1 -1
- package/_esm/actions/morpho/user-positions/getMorphoMarketUserPositions.js +12 -8
- package/_esm/actions/morpho/user-positions/getMorphoMarketUserPositions.js.map +1 -1
- package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositions.js +12 -8
- package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositions.js.map +1 -1
- package/_esm/actions/retry.js +45 -15
- package/_esm/actions/retry.js.map +1 -1
- package/_esm/client/createActions.js +2 -0
- package/_esm/client/createActions.js.map +1 -1
- package/_esm/client/createMoonwellClient.js.map +1 -1
- package/_esm/common/error.js +49 -0
- package/_esm/common/error.js.map +1 -1
- package/_esm/common/index.js +1 -1
- package/_esm/common/index.js.map +1 -1
- package/_esm/common/readAcrossEnvironments.js +30 -0
- package/_esm/common/readAcrossEnvironments.js.map +1 -0
- package/_esm/environments/index.js.map +1 -1
- package/_esm/environments/types/config.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/index.js +1 -0
- package/_esm/index.js.map +1 -1
- package/_types/actions/axiosWithRetry.d.ts +1 -0
- package/_types/actions/axiosWithRetry.d.ts.map +1 -1
- package/_types/actions/core/getUserBalances.d.ts.map +1 -1
- package/_types/actions/core/markets/common.d.ts.map +1 -1
- package/_types/actions/core/markets/getMarkets.d.ts.map +1 -1
- package/_types/actions/core/user-positions/common.d.ts.map +1 -1
- package/_types/actions/core/user-positions/getUserPositions.d.ts +5 -0
- package/_types/actions/core/user-positions/getUserPositions.d.ts.map +1 -1
- package/_types/actions/governance/proposals/common.d.ts.map +1 -1
- package/_types/actions/index.d.ts +1 -0
- package/_types/actions/index.d.ts.map +1 -1
- package/_types/actions/morpho/markets/common.d.ts +7 -10
- package/_types/actions/morpho/markets/common.d.ts.map +1 -1
- package/_types/actions/morpho/markets/getMorphoMarket.d.ts +2 -0
- package/_types/actions/morpho/markets/getMorphoMarket.d.ts.map +1 -1
- package/_types/actions/morpho/markets/getMorphoMarkets.d.ts +2 -0
- package/_types/actions/morpho/markets/getMorphoMarkets.d.ts.map +1 -1
- package/_types/actions/morpho/markets/getMorphoMarketsSharedLiquidity.d.ts +17 -0
- package/_types/actions/morpho/markets/getMorphoMarketsSharedLiquidity.d.ts.map +1 -0
- package/_types/actions/morpho/user-positions/common.d.ts.map +1 -1
- package/_types/actions/morpho/user-positions/getMorphoMarketUserPositions.d.ts +5 -0
- package/_types/actions/morpho/user-positions/getMorphoMarketUserPositions.d.ts.map +1 -1
- package/_types/actions/morpho/user-positions/getMorphoVaultUserPositions.d.ts +5 -0
- package/_types/actions/morpho/user-positions/getMorphoVaultUserPositions.d.ts.map +1 -1
- package/_types/actions/retry.d.ts +5 -4
- package/_types/actions/retry.d.ts.map +1 -1
- package/_types/client/createActions.d.ts +2 -0
- package/_types/client/createActions.d.ts.map +1 -1
- package/_types/client/createMoonwellClient.d.ts +2 -5
- package/_types/client/createMoonwellClient.d.ts.map +1 -1
- package/_types/common/error.d.ts +31 -0
- package/_types/common/error.d.ts.map +1 -1
- package/_types/common/index.d.ts +2 -2
- package/_types/common/index.d.ts.map +1 -1
- package/_types/common/readAcrossEnvironments.d.ts +23 -0
- package/_types/common/readAcrossEnvironments.d.ts.map +1 -0
- package/_types/environments/index.d.ts +2 -2
- package/_types/environments/index.d.ts.map +1 -1
- package/_types/environments/types/config.d.ts +8 -8
- package/_types/environments/types/config.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/index.d.ts +3 -1
- package/_types/index.d.ts.map +1 -1
- package/_types/types/morphoMarket.d.ts +9 -0
- package/_types/types/morphoMarket.d.ts.map +1 -1
- package/actions/axiosWithRetry.ts +19 -13
- package/actions/core/getUserBalances.ts +25 -31
- package/actions/core/markets/common.ts +44 -43
- package/actions/core/markets/getMarkets.ts +9 -5
- package/actions/core/user-positions/common.ts +107 -111
- package/actions/core/user-positions/getUserPositions.ts +11 -10
- package/actions/governance/proposals/common.ts +0 -3
- package/actions/index.ts +5 -0
- package/actions/morpho/markets/common.ts +289 -125
- package/actions/morpho/markets/getMorphoMarket.ts +3 -0
- package/actions/morpho/markets/getMorphoMarkets.ts +3 -0
- package/actions/morpho/markets/getMorphoMarketsSharedLiquidity.ts +93 -0
- package/actions/morpho/user-positions/common.ts +48 -42
- package/actions/morpho/user-positions/getMorphoMarketUserPositions.ts +14 -15
- package/actions/morpho/user-positions/getMorphoVaultUserPositions.ts +14 -15
- package/actions/retry.ts +53 -18
- package/client/createActions.ts +13 -0
- package/client/createMoonwellClient.ts +2 -4
- package/common/error.ts +45 -0
- package/common/index.ts +2 -2
- package/common/readAcrossEnvironments.ts +45 -0
- package/environments/index.ts +6 -1
- package/environments/types/config.ts +10 -8
- package/errors/version.ts +1 -1
- package/index.ts +3 -0
- package/package.json +1 -1
- package/types/morphoMarket.ts +10 -0
|
@@ -4,6 +4,7 @@ import type { MultichainReturnType } from "../../../common/types.js";
|
|
|
4
4
|
import type { Environment } from "../../../environments/index.js";
|
|
5
5
|
import type {
|
|
6
6
|
MorphoMarket,
|
|
7
|
+
MorphoMarketSharedLiquidity,
|
|
7
8
|
PublicAllocatorSharedLiquidityType,
|
|
8
9
|
} from "../../../types/morphoMarket.js";
|
|
9
10
|
import type { MorphoReward } from "../../../types/morphoReward.js";
|
|
@@ -45,14 +46,129 @@ export interface LunarSharedLiquidityResponse {
|
|
|
45
46
|
markets: Record<string, LunarMarketLiveData>;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
function parseLiquidityQuantity(
|
|
50
|
+
value: unknown,
|
|
51
|
+
field: string,
|
|
52
|
+
raw = false,
|
|
53
|
+
): number {
|
|
54
|
+
// Raw uint quantities routinely exceed Number.MAX_SAFE_INTEGER. Validate the
|
|
55
|
+
// integer string, not its safe-integer range; keep the existing numeric units.
|
|
56
|
+
const pattern = raw ? /^\d+$/ : /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
57
|
+
if (typeof value !== "string" || !pattern.test(value)) {
|
|
58
|
+
throw new TypeError(`Invalid shared-liquidity quantity: ${field}`);
|
|
59
|
+
}
|
|
60
|
+
const quantity = Number(value);
|
|
61
|
+
if (!Number.isFinite(quantity)) {
|
|
62
|
+
throw new TypeError(`Invalid shared-liquidity quantity: ${field}`);
|
|
63
|
+
}
|
|
64
|
+
return quantity;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function validateLoanDecimals(value: unknown): number {
|
|
68
|
+
if (
|
|
69
|
+
typeof value !== "number" ||
|
|
70
|
+
!Number.isInteger(value) ||
|
|
71
|
+
value < 0 ||
|
|
72
|
+
value > 255
|
|
73
|
+
) {
|
|
74
|
+
throw new TypeError("Invalid shared-liquidity loan token decimals");
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function validatedMarketLiquidity(
|
|
80
|
+
data: LunarSharedLiquidityResponse,
|
|
81
|
+
): Map<string, number> {
|
|
82
|
+
if (
|
|
83
|
+
!data ||
|
|
84
|
+
!Array.isArray(data.vaults) ||
|
|
85
|
+
!data.markets ||
|
|
86
|
+
typeof data.markets !== "object" ||
|
|
87
|
+
Array.isArray(data.markets)
|
|
88
|
+
) {
|
|
89
|
+
throw new TypeError("Invalid shared-liquidity response");
|
|
90
|
+
}
|
|
91
|
+
for (const vault of data.vaults) {
|
|
92
|
+
parseLiquidityQuantity(vault.fee, "vault.fee", true);
|
|
93
|
+
for (const market of vault.markets) {
|
|
94
|
+
for (const field of [
|
|
95
|
+
"flowCapIn",
|
|
96
|
+
"flowCapOut",
|
|
97
|
+
"supplyCap",
|
|
98
|
+
"vaultSupplyShares",
|
|
99
|
+
"vaultSupplyAssets",
|
|
100
|
+
] as const) {
|
|
101
|
+
parseLiquidityQuantity(
|
|
102
|
+
market[field],
|
|
103
|
+
`${market.marketId}.${field}`,
|
|
104
|
+
true,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (typeof market.supplyCapEnabled !== "boolean") {
|
|
108
|
+
throw new TypeError("Invalid shared-liquidity supplyCapEnabled");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return new Map(
|
|
113
|
+
Object.entries(data.markets).map(([marketId, market]) => {
|
|
114
|
+
if (market.loanToken !== undefined) {
|
|
115
|
+
validateLoanDecimals(market.loanToken.decimals);
|
|
116
|
+
}
|
|
117
|
+
for (const field of ["totalSupplyAssets", "totalBorrowAssets"] as const) {
|
|
118
|
+
if (market[field] !== undefined) {
|
|
119
|
+
parseLiquidityQuantity(market[field], `${marketId}.${field}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const liquidity =
|
|
123
|
+
market.totalLiquidity !== undefined
|
|
124
|
+
? parseLiquidityQuantity(
|
|
125
|
+
market.totalLiquidity,
|
|
126
|
+
`${marketId}.totalLiquidity`,
|
|
127
|
+
)
|
|
128
|
+
: parseLiquidityQuantity(
|
|
129
|
+
market.totalSupplyAssets,
|
|
130
|
+
`${marketId}.totalSupplyAssets`,
|
|
131
|
+
) -
|
|
132
|
+
parseLiquidityQuantity(
|
|
133
|
+
market.totalBorrowAssets,
|
|
134
|
+
`${marketId}.totalBorrowAssets`,
|
|
135
|
+
);
|
|
136
|
+
if (liquidity < 0) {
|
|
137
|
+
throw new TypeError(`Negative shared liquidity for ${marketId}`);
|
|
138
|
+
}
|
|
139
|
+
return [marketId, liquidity];
|
|
140
|
+
}),
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export async function fetchSharedLiquidityFromLunar(
|
|
49
145
|
lunarIndexerUrl: string,
|
|
50
146
|
chainId: number,
|
|
147
|
+
options: { signal?: AbortSignal; timeoutMs?: number } = {},
|
|
51
148
|
): Promise<LunarSharedLiquidityResponse> {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
149
|
+
// One budget for the request AND its retries. The endpoint often takes more
|
|
150
|
+
// than five seconds, so let it finish instead of restarting the same work.
|
|
151
|
+
const timeoutMs = options.timeoutMs ?? 15_000;
|
|
152
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
153
|
+
throw new RangeError(
|
|
154
|
+
"Shared-liquidity timeoutMs must be positive and finite",
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
const controller = new AbortController();
|
|
158
|
+
const abort = (): void => controller.abort();
|
|
159
|
+
if (options.signal?.aborted) abort();
|
|
160
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
161
|
+
const timer = setTimeout(abort, timeoutMs);
|
|
162
|
+
try {
|
|
163
|
+
const response = await getWithRetry<LunarSharedLiquidityResponse>(
|
|
164
|
+
`${lunarIndexerUrl}/api/v1/isolated/shared-liquidity/${chainId}`,
|
|
165
|
+
{ timeout: timeoutMs, signal: controller.signal },
|
|
166
|
+
);
|
|
167
|
+
return response.data;
|
|
168
|
+
} finally {
|
|
169
|
+
clearTimeout(timer);
|
|
170
|
+
options.signal?.removeEventListener("abort", abort);
|
|
171
|
+
}
|
|
56
172
|
}
|
|
57
173
|
|
|
58
174
|
export function computeSharedLiquidityFromLunar(
|
|
@@ -69,7 +185,9 @@ export function computeSharedLiquidityFromLunar(
|
|
|
69
185
|
}
|
|
70
186
|
>,
|
|
71
187
|
chainId: number,
|
|
72
|
-
):
|
|
188
|
+
): MorphoMarketSharedLiquidity[] {
|
|
189
|
+
// Validate the complete response before building any successful allocations.
|
|
190
|
+
const liquidityByMarket = validatedMarketLiquidity(data);
|
|
73
191
|
return targetMarkets.map((targetMarket) => {
|
|
74
192
|
const targetId = targetMarket.toLowerCase();
|
|
75
193
|
const r: PublicAllocatorSharedLiquidityType[] = [];
|
|
@@ -83,10 +201,11 @@ export function computeSharedLiquidityFromLunar(
|
|
|
83
201
|
// (wei-like). Markets data (totalSupplyAssets, totalBorrowAssets, totalLiquidity)
|
|
84
202
|
// is already in token units (divided by decimals). We convert vault raw values
|
|
85
203
|
// to token units using the loan token decimals before comparing.
|
|
86
|
-
const targetLoanDecimals =
|
|
204
|
+
const targetLoanDecimals = validateLoanDecimals(
|
|
87
205
|
targetLiveData?.loanToken?.decimals ??
|
|
88
|
-
|
|
89
|
-
|
|
206
|
+
targetParams?.loanToken.decimals ??
|
|
207
|
+
18,
|
|
208
|
+
);
|
|
90
209
|
const targetScale = 10 ** targetLoanDecimals;
|
|
91
210
|
|
|
92
211
|
for (const vault of data.vaults) {
|
|
@@ -135,25 +254,25 @@ export function computeSharedLiquidityFromLunar(
|
|
|
135
254
|
|
|
136
255
|
const sourceLiveData =
|
|
137
256
|
data.markets[sourceMarket.marketId.toLowerCase()];
|
|
138
|
-
|
|
257
|
+
const liquidity = liquidityByMarket.get(
|
|
258
|
+
sourceMarket.marketId.toLowerCase(),
|
|
259
|
+
);
|
|
260
|
+
// The indexer can omit an entire source record. Preserve that existing
|
|
261
|
+
// skip behavior; quantities in every returned record were validated above.
|
|
262
|
+
if (!sourceLiveData || liquidity === undefined) continue;
|
|
139
263
|
|
|
140
|
-
const sourceLoanDecimals =
|
|
264
|
+
const sourceLoanDecimals = validateLoanDecimals(
|
|
141
265
|
sourceLiveData.loanToken?.decimals ??
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
266
|
+
marketParamsMap.get(sourceMarket.marketId.toLowerCase())?.loanToken
|
|
267
|
+
.decimals ??
|
|
268
|
+
18,
|
|
269
|
+
);
|
|
145
270
|
const sourceScale = 10 ** sourceLoanDecimals;
|
|
146
271
|
|
|
147
272
|
const vaultSupplyInSource =
|
|
148
273
|
Number(sourceMarket.vaultSupplyAssets) / sourceScale;
|
|
149
274
|
const maxOut = Number(sourceMarket.flowCapOut) / sourceScale;
|
|
150
275
|
|
|
151
|
-
// Use pre-computed totalLiquidity if available, else derive from supply/borrow
|
|
152
|
-
const liquidity = sourceLiveData.totalLiquidity
|
|
153
|
-
? Number(sourceLiveData.totalLiquidity)
|
|
154
|
-
: Number(sourceLiveData.totalSupplyAssets ?? 0) -
|
|
155
|
-
Number(sourceLiveData.totalBorrowAssets ?? 0);
|
|
156
|
-
|
|
157
276
|
if (vaultSupplyInSource > 0 && maxOut > 0 && liquidity > 0) {
|
|
158
277
|
const sourceParams = marketParamsMap.get(
|
|
159
278
|
sourceMarket.marketId.toLowerCase(),
|
|
@@ -219,6 +338,7 @@ export async function getMorphoMarketsData(params: {
|
|
|
219
338
|
environments: Environment[];
|
|
220
339
|
markets?: string[] | undefined;
|
|
221
340
|
includeRewards?: boolean | undefined;
|
|
341
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
222
342
|
}): Promise<MorphoMarket[]> {
|
|
223
343
|
const { environments } = params;
|
|
224
344
|
|
|
@@ -240,6 +360,7 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
240
360
|
environments: Environment[];
|
|
241
361
|
markets?: string[] | undefined;
|
|
242
362
|
includeRewards?: boolean | undefined;
|
|
363
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
243
364
|
}): Promise<MorphoMarket[]> {
|
|
244
365
|
const { environments } = params;
|
|
245
366
|
|
|
@@ -281,7 +402,11 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
281
402
|
: [],
|
|
282
403
|
);
|
|
283
404
|
|
|
284
|
-
const initialMarkets:
|
|
405
|
+
const initialMarkets: {
|
|
406
|
+
chainId: number;
|
|
407
|
+
marketId: string;
|
|
408
|
+
marketKey: string;
|
|
409
|
+
}[] = [];
|
|
285
410
|
fulfilledMarketsInfo.forEach(({ environment, marketsInfo }) => {
|
|
286
411
|
marketsInfo.forEach((marketInfo) => {
|
|
287
412
|
const marketKey = Object.keys(environment.config.morphoMarkets).find(
|
|
@@ -298,7 +423,7 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
298
423
|
chainId: environment.chainId,
|
|
299
424
|
marketId: marketInfo.marketId,
|
|
300
425
|
marketKey,
|
|
301
|
-
}
|
|
426
|
+
});
|
|
302
427
|
});
|
|
303
428
|
});
|
|
304
429
|
|
|
@@ -308,6 +433,7 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
308
433
|
const rewardsData = await getMorphoMarketRewards(
|
|
309
434
|
rewardEnvironment,
|
|
310
435
|
initialMarkets,
|
|
436
|
+
params,
|
|
311
437
|
);
|
|
312
438
|
const rewardsDataByChainAndMarket = new Map<
|
|
313
439
|
string,
|
|
@@ -493,6 +619,10 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
493
619
|
rewards: [],
|
|
494
620
|
publicAllocatorSharedLiquidity:
|
|
495
621
|
marketRewardData?.publicAllocatorSharedLiquidity ?? [],
|
|
622
|
+
sharedLiquidityStatus:
|
|
623
|
+
params.includeSharedLiquidity === false
|
|
624
|
+
? "not-requested"
|
|
625
|
+
: (marketRewardData?.sharedLiquidityStatus ?? "unavailable"),
|
|
496
626
|
};
|
|
497
627
|
|
|
498
628
|
return [mapping];
|
|
@@ -516,17 +646,11 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
516
646
|
return environment?.custom.morpho?.minimalDeployment === false;
|
|
517
647
|
});
|
|
518
648
|
|
|
519
|
-
const rewards = await getMorphoMarketRewards(
|
|
520
|
-
params.environments.find((env) => env.custom?.morpho?.apiUrl) ??
|
|
521
|
-
params.environments[0],
|
|
522
|
-
markets,
|
|
523
|
-
);
|
|
524
|
-
|
|
525
649
|
markets.forEach((market) => {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
650
|
+
// Collateral, rewards and optional liquidity came from the same GraphQL
|
|
651
|
+
// response above. Do not repeat that expensive enrichment request.
|
|
652
|
+
const marketReward = rewardsDataByChainAndMarket.get(
|
|
653
|
+
`${market.chainId}-${market.marketId.toLowerCase()}`,
|
|
530
654
|
);
|
|
531
655
|
if (marketReward) {
|
|
532
656
|
market.rewards = marketReward.rewards;
|
|
@@ -556,13 +680,6 @@ async function getMorphoMarketsDataFromOnChain(params: {
|
|
|
556
680
|
});
|
|
557
681
|
}
|
|
558
682
|
|
|
559
|
-
type GetMorphoMarketsPublicAllocatorSharedLiquidityReturnType = {
|
|
560
|
-
chainId: number;
|
|
561
|
-
marketId: string;
|
|
562
|
-
reallocatableLiquidityAssets: Amount;
|
|
563
|
-
publicAllocatorSharedLiquidity: PublicAllocatorSharedLiquidityType[];
|
|
564
|
-
};
|
|
565
|
-
|
|
566
683
|
type GetMorphoMarketsRewardsReturnType = {
|
|
567
684
|
chainId: number;
|
|
568
685
|
marketId: string;
|
|
@@ -571,11 +688,16 @@ type GetMorphoMarketsRewardsReturnType = {
|
|
|
571
688
|
reallocatableLiquidityAssets: Amount;
|
|
572
689
|
publicAllocatorSharedLiquidity: PublicAllocatorSharedLiquidityType[];
|
|
573
690
|
rewards: Required<MorphoReward>[];
|
|
691
|
+
sharedLiquidityStatus: "available" | "unavailable" | "not-requested";
|
|
574
692
|
};
|
|
575
693
|
|
|
576
694
|
async function getMorphoMarketRewards(
|
|
577
695
|
environment: Environment,
|
|
578
696
|
markets: { marketId: string; chainId: number }[],
|
|
697
|
+
options: {
|
|
698
|
+
includeRewards?: boolean | undefined;
|
|
699
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
700
|
+
},
|
|
579
701
|
): Promise<GetMorphoMarketsRewardsReturnType[]> {
|
|
580
702
|
if (markets.length === 0) {
|
|
581
703
|
return [];
|
|
@@ -591,7 +713,10 @@ async function getMorphoMarketRewards(
|
|
|
591
713
|
id
|
|
592
714
|
}
|
|
593
715
|
}
|
|
594
|
-
|
|
716
|
+
${
|
|
717
|
+
options.includeSharedLiquidity === false
|
|
718
|
+
? ""
|
|
719
|
+
: `reallocatableLiquidityAssets
|
|
595
720
|
publicAllocatorSharedLiquidity {
|
|
596
721
|
assets
|
|
597
722
|
vault {
|
|
@@ -621,6 +746,8 @@ async function getMorphoMarketRewards(
|
|
|
621
746
|
lltv
|
|
622
747
|
}
|
|
623
748
|
}
|
|
749
|
+
`
|
|
750
|
+
}
|
|
624
751
|
collateralAsset {
|
|
625
752
|
decimals
|
|
626
753
|
}
|
|
@@ -631,7 +758,9 @@ async function getMorphoMarketRewards(
|
|
|
631
758
|
state {
|
|
632
759
|
collateralAssets
|
|
633
760
|
collateralAssetsUsd
|
|
634
|
-
|
|
761
|
+
${
|
|
762
|
+
options.includeRewards
|
|
763
|
+
? `rewards {
|
|
635
764
|
asset {
|
|
636
765
|
address
|
|
637
766
|
symbol
|
|
@@ -640,6 +769,8 @@ async function getMorphoMarketRewards(
|
|
|
640
769
|
}
|
|
641
770
|
supplyApr
|
|
642
771
|
borrowApr
|
|
772
|
+
}`
|
|
773
|
+
: ""
|
|
643
774
|
}
|
|
644
775
|
}
|
|
645
776
|
marketId
|
|
@@ -718,7 +849,7 @@ async function getMorphoMarketRewards(
|
|
|
718
849
|
chainId: item.morphoBlue.chain.id,
|
|
719
850
|
marketId: item.marketId,
|
|
720
851
|
reallocatableLiquidityAssets: new Amount(
|
|
721
|
-
BigInt(item.reallocatableLiquidityAssets),
|
|
852
|
+
BigInt(item.reallocatableLiquidityAssets ?? "0"),
|
|
722
853
|
loanAssetDecimals,
|
|
723
854
|
),
|
|
724
855
|
// Note: The Morpho GraphQL API may return null for collateralAssets and
|
|
@@ -732,38 +863,49 @@ async function getMorphoMarketRewards(
|
|
|
732
863
|
)
|
|
733
864
|
: null,
|
|
734
865
|
collateralAssetsUsd: item.state.collateralAssetsUsd ?? null,
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
irmAddress: item.allocationMarket.irmAddress,
|
|
762
|
-
lltv: item.allocationMarket.lltv,
|
|
866
|
+
sharedLiquidityStatus:
|
|
867
|
+
options.includeSharedLiquidity === false
|
|
868
|
+
? "not-requested"
|
|
869
|
+
: item.publicAllocatorSharedLiquidity
|
|
870
|
+
? "available"
|
|
871
|
+
: "unavailable",
|
|
872
|
+
publicAllocatorSharedLiquidity: (options.includeSharedLiquidity ===
|
|
873
|
+
false
|
|
874
|
+
? []
|
|
875
|
+
: (item.publicAllocatorSharedLiquidity ?? [])
|
|
876
|
+
).map((item) => ({
|
|
877
|
+
assets: Number(item.assets) / 10 ** loanAssetDecimals,
|
|
878
|
+
vault: {
|
|
879
|
+
address: item.vault.address,
|
|
880
|
+
name: item.vault.name,
|
|
881
|
+
// The Morpho API renamed Market.uniqueKey to marketId; map it
|
|
882
|
+
// back to keep the SDK's public types unchanged.
|
|
883
|
+
publicAllocatorConfig: {
|
|
884
|
+
fee: item.vault.publicAllocatorConfig.fee,
|
|
885
|
+
flowCaps: item.vault.publicAllocatorConfig.flowCaps.map(
|
|
886
|
+
(flowCap) => ({
|
|
887
|
+
market: { uniqueKey: flowCap.market.marketId },
|
|
888
|
+
maxIn: flowCap.maxIn,
|
|
889
|
+
maxOut: flowCap.maxOut,
|
|
890
|
+
}),
|
|
891
|
+
),
|
|
763
892
|
},
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
|
|
893
|
+
},
|
|
894
|
+
allocationMarket: {
|
|
895
|
+
uniqueKey: item.allocationMarket.marketId,
|
|
896
|
+
loanAsset: item.allocationMarket.loanAsset,
|
|
897
|
+
...(item.allocationMarket.collateralAsset
|
|
898
|
+
? { collateralAsset: item.allocationMarket.collateralAsset }
|
|
899
|
+
: {}),
|
|
900
|
+
oracleAddress: item.allocationMarket.oracleAddress,
|
|
901
|
+
irmAddress: item.allocationMarket.irmAddress,
|
|
902
|
+
lltv: item.allocationMarket.lltv,
|
|
903
|
+
},
|
|
904
|
+
})),
|
|
905
|
+
rewards: (options.includeRewards
|
|
906
|
+
? (item.state?.rewards ?? [])
|
|
907
|
+
: []
|
|
908
|
+
).map((reward) => {
|
|
767
909
|
//Supply APR is used only for vaults, zeroing it for now to avoid confusion
|
|
768
910
|
// Morpho removed the per-token amount fields from the API
|
|
769
911
|
// (MarketStateReward.amountPerBorrowedToken et al.), so reward
|
|
@@ -795,6 +937,7 @@ async function getMorphoMarketsDataFromIndexer(params: {
|
|
|
795
937
|
environments: Environment[];
|
|
796
938
|
markets?: string[] | undefined;
|
|
797
939
|
includeRewards?: boolean | undefined;
|
|
940
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
798
941
|
}): Promise<MorphoMarket[]> {
|
|
799
942
|
const { environments } = params;
|
|
800
943
|
|
|
@@ -866,6 +1009,7 @@ async function getMorphoMarketsDataFromIndexer(params: {
|
|
|
866
1009
|
environments: failedEnvironments,
|
|
867
1010
|
markets: params.markets,
|
|
868
1011
|
includeRewards: params.includeRewards,
|
|
1012
|
+
includeSharedLiquidity: params.includeSharedLiquidity,
|
|
869
1013
|
});
|
|
870
1014
|
} catch (rpcError) {
|
|
871
1015
|
console.warn(
|
|
@@ -883,61 +1027,69 @@ async function getMorphoMarketsDataFromIndexer(params: {
|
|
|
883
1027
|
|
|
884
1028
|
// Fetch shared liquidity from lunar-indexer.
|
|
885
1029
|
const sharedLiquiditySettlements = await Promise.allSettled(
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1030
|
+
(params.includeSharedLiquidity === false ? [] : fulfilledMarkets).map(
|
|
1031
|
+
async ({
|
|
1032
|
+
environment,
|
|
1033
|
+
markets,
|
|
1034
|
+
}): Promise<{
|
|
1035
|
+
environment: Environment;
|
|
1036
|
+
data: MorphoMarketSharedLiquidity[];
|
|
1037
|
+
}> => {
|
|
1038
|
+
const lunarIndexerUrl = environment.lunarIndexerUrl;
|
|
1039
|
+
if (!lunarIndexerUrl)
|
|
1040
|
+
return {
|
|
1041
|
+
environment,
|
|
1042
|
+
data: [],
|
|
1043
|
+
};
|
|
893
1044
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1045
|
+
const marketParamsMap = new Map(
|
|
1046
|
+
markets.map((m) => [
|
|
1047
|
+
m.marketId.toLowerCase(),
|
|
1048
|
+
{
|
|
1049
|
+
oracle: m.oracle,
|
|
1050
|
+
irm: m.irm,
|
|
1051
|
+
lltv: m.lltv,
|
|
1052
|
+
loanToken: {
|
|
1053
|
+
address: m.loanToken.address,
|
|
1054
|
+
decimals: m.loanToken.decimals,
|
|
1055
|
+
},
|
|
1056
|
+
collateralToken: {
|
|
1057
|
+
address: m.collateralToken.address,
|
|
1058
|
+
decimals: m.collateralToken.decimals,
|
|
1059
|
+
},
|
|
908
1060
|
},
|
|
909
|
-
|
|
910
|
-
]),
|
|
911
|
-
);
|
|
912
|
-
|
|
913
|
-
try {
|
|
914
|
-
const rawData = await fetchSharedLiquidityFromLunar(
|
|
915
|
-
lunarIndexerUrl,
|
|
916
|
-
environment.chainId,
|
|
1061
|
+
]),
|
|
917
1062
|
);
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
rawData
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1063
|
+
|
|
1064
|
+
try {
|
|
1065
|
+
const rawData = await fetchSharedLiquidityFromLunar(
|
|
1066
|
+
lunarIndexerUrl,
|
|
1067
|
+
environment.chainId,
|
|
1068
|
+
);
|
|
1069
|
+
const marketIds = markets.map((m) => m.marketId);
|
|
1070
|
+
const data = computeSharedLiquidityFromLunar(
|
|
1071
|
+
rawData,
|
|
1072
|
+
marketIds,
|
|
1073
|
+
marketParamsMap,
|
|
1074
|
+
environment.chainId,
|
|
1075
|
+
);
|
|
1076
|
+
return { environment, data };
|
|
1077
|
+
} catch (error) {
|
|
1078
|
+
console.warn(
|
|
1079
|
+
`[getMorphoMarketsData] Lunar shared liquidity failed for chain ${environment.chainId}:`,
|
|
1080
|
+
error,
|
|
1081
|
+
);
|
|
1082
|
+
environment.onError?.(error, {
|
|
1083
|
+
source: "morpho-shared-liquidity",
|
|
1084
|
+
chainId: environment.chainId,
|
|
1085
|
+
});
|
|
1086
|
+
return {
|
|
1087
|
+
environment,
|
|
1088
|
+
data: [],
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
},
|
|
1092
|
+
),
|
|
941
1093
|
);
|
|
942
1094
|
|
|
943
1095
|
const fulfilledSharedLiquidity = sharedLiquiditySettlements.flatMap((s) =>
|
|
@@ -1027,6 +1179,18 @@ async function getMorphoMarketsDataFromIndexer(params: {
|
|
|
1027
1179
|
environment,
|
|
1028
1180
|
rewardsDataMap,
|
|
1029
1181
|
sharedLiquidityMap,
|
|
1182
|
+
).map(
|
|
1183
|
+
(market): MorphoMarket => ({
|
|
1184
|
+
...market,
|
|
1185
|
+
sharedLiquidityStatus:
|
|
1186
|
+
params.includeSharedLiquidity === false
|
|
1187
|
+
? "not-requested"
|
|
1188
|
+
: sharedLiquidityMap.has(
|
|
1189
|
+
`${market.chainId}-${market.marketId.toLowerCase()}`,
|
|
1190
|
+
)
|
|
1191
|
+
? "available"
|
|
1192
|
+
: "unavailable",
|
|
1193
|
+
}),
|
|
1030
1194
|
);
|
|
1031
1195
|
},
|
|
1032
1196
|
);
|
|
@@ -17,6 +17,8 @@ export type GetMorphoMarketParameters<
|
|
|
17
17
|
> = NetworkParameterType<environments, network> &
|
|
18
18
|
MorphoMarketParameterType<network> & {
|
|
19
19
|
includeRewards?: boolean | undefined;
|
|
20
|
+
/** Defaults to true. Disable to load base market data independently. */
|
|
21
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export type GetMorphoMarketReturnType = Promise<MorphoMarket | undefined>;
|
|
@@ -47,6 +49,7 @@ export async function getMorphoMarket<
|
|
|
47
49
|
environments: [environment],
|
|
48
50
|
markets: [marketId],
|
|
49
51
|
includeRewards: args.includeRewards,
|
|
52
|
+
includeSharedLiquidity: args.includeSharedLiquidity,
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
return first(markets);
|
|
@@ -11,6 +11,8 @@ export type GetMorphoMarketsParameters<
|
|
|
11
11
|
network extends Chain | undefined,
|
|
12
12
|
> = OptionalNetworkParameterType<environments, network> & {
|
|
13
13
|
includeRewards?: boolean | undefined;
|
|
14
|
+
/** Defaults to true. Disable to load base market data independently. */
|
|
15
|
+
includeSharedLiquidity?: boolean | undefined;
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export type GetMorphoMarketsReturnType = Promise<MorphoMarket[]>;
|
|
@@ -32,6 +34,7 @@ export async function getMorphoMarkets<
|
|
|
32
34
|
const result = await getMorphoMarketsData({
|
|
33
35
|
environments: environments,
|
|
34
36
|
includeRewards: args?.includeRewards,
|
|
37
|
+
includeSharedLiquidity: args?.includeSharedLiquidity,
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
logger.end(logId);
|