@morpho-org/consumer-sdk 0.3.0 → 0.5.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.
Files changed (82) hide show
  1. package/README.md +301 -41
  2. package/lib/actions/index.d.ts +2 -0
  3. package/lib/actions/index.js +2 -0
  4. package/lib/actions/marketV1/borrow.d.ts +34 -0
  5. package/lib/actions/marketV1/borrow.js +62 -0
  6. package/lib/actions/marketV1/buildReallocationActions.d.ts +17 -0
  7. package/lib/actions/marketV1/buildReallocationActions.js +36 -0
  8. package/lib/actions/marketV1/index.d.ts +6 -0
  9. package/lib/actions/marketV1/index.js +22 -0
  10. package/lib/actions/marketV1/repay.d.ts +44 -0
  11. package/lib/actions/marketV1/repay.js +93 -0
  12. package/lib/actions/marketV1/repayWithdrawCollateral.d.ts +51 -0
  13. package/lib/actions/marketV1/repayWithdrawCollateral.js +108 -0
  14. package/lib/actions/marketV1/supplyCollateral.d.ts +28 -0
  15. package/lib/actions/marketV1/supplyCollateral.js +85 -0
  16. package/lib/actions/marketV1/supplyCollateralBorrow.d.ts +37 -0
  17. package/lib/actions/marketV1/supplyCollateralBorrow.js +109 -0
  18. package/lib/actions/marketV1/withdrawCollateral.d.ts +28 -0
  19. package/lib/actions/marketV1/withdrawCollateral.js +51 -0
  20. package/lib/actions/requirements/encode/encodeErc20Permit.js +4 -1
  21. package/lib/actions/requirements/encode/encodeErc20Permit2.js +4 -1
  22. package/lib/actions/requirements/getMorphoAuthorizationRequirement.d.ts +21 -0
  23. package/lib/actions/requirements/getMorphoAuthorizationRequirement.js +55 -0
  24. package/lib/actions/requirements/getRequirements.js +3 -0
  25. package/lib/actions/requirements/getRequirementsAction.d.ts +2 -2
  26. package/lib/actions/requirements/getRequirementsAction.js +7 -7
  27. package/lib/actions/requirements/index.d.ts +1 -0
  28. package/lib/actions/requirements/index.js +1 -0
  29. package/lib/actions/vaultV1/deposit.d.ts +41 -0
  30. package/lib/actions/vaultV1/deposit.js +116 -0
  31. package/lib/actions/vaultV1/index.d.ts +3 -0
  32. package/lib/actions/vaultV1/index.js +19 -0
  33. package/lib/actions/vaultV1/redeem.d.ts +29 -0
  34. package/lib/actions/vaultV1/redeem.js +48 -0
  35. package/lib/actions/vaultV1/withdraw.d.ts +29 -0
  36. package/lib/actions/vaultV1/withdraw.js +48 -0
  37. package/lib/actions/vaultV2/deposit.d.ts +20 -25
  38. package/lib/actions/vaultV2/deposit.js +78 -40
  39. package/lib/actions/vaultV2/forceRedeem.js +2 -2
  40. package/lib/actions/vaultV2/forceWithdraw.d.ts +2 -2
  41. package/lib/actions/vaultV2/forceWithdraw.js +12 -8
  42. package/lib/actions/vaultV2/redeem.js +2 -2
  43. package/lib/actions/vaultV2/withdraw.d.ts +3 -3
  44. package/lib/actions/vaultV2/withdraw.js +6 -6
  45. package/lib/client/morphoClient.d.ts +4 -1
  46. package/lib/client/morphoClient.js +6 -0
  47. package/lib/client/morphoViemExtension.d.ts +12 -9
  48. package/lib/client/morphoViemExtension.js +12 -9
  49. package/lib/entities/index.d.ts +2 -0
  50. package/lib/entities/index.js +2 -0
  51. package/lib/entities/marketV1/index.d.ts +1 -0
  52. package/lib/entities/marketV1/index.js +17 -0
  53. package/lib/entities/marketV1/marketV1.d.ts +290 -0
  54. package/lib/entities/marketV1/marketV1.js +528 -0
  55. package/lib/entities/vaultV1/index.d.ts +1 -0
  56. package/lib/entities/vaultV1/index.js +17 -0
  57. package/lib/entities/vaultV1/vaultV1.d.ts +95 -0
  58. package/lib/entities/vaultV1/vaultV1.js +129 -0
  59. package/lib/entities/vaultV2/vaultV2.d.ts +24 -21
  60. package/lib/entities/vaultV2/vaultV2.js +43 -16
  61. package/lib/helpers/computeReallocations.d.ts +23 -0
  62. package/lib/helpers/computeReallocations.js +98 -0
  63. package/lib/helpers/constant.d.ts +5 -0
  64. package/lib/helpers/constant.js +6 -1
  65. package/lib/helpers/encodeDeallocation.js +3 -3
  66. package/lib/helpers/index.d.ts +3 -0
  67. package/lib/helpers/index.js +18 -1
  68. package/lib/helpers/slippage.d.ts +46 -0
  69. package/lib/helpers/slippage.js +73 -0
  70. package/lib/helpers/validate.d.ts +150 -0
  71. package/lib/helpers/validate.js +279 -0
  72. package/lib/types/action.d.ts +113 -6
  73. package/lib/types/action.js +12 -1
  74. package/lib/types/client.d.ts +4 -1
  75. package/lib/types/deallocation.d.ts +1 -1
  76. package/lib/types/error.d.ts +127 -4
  77. package/lib/types/error.js +210 -12
  78. package/lib/types/index.d.ts +1 -0
  79. package/lib/types/index.js +1 -0
  80. package/lib/types/sharedLiquidity.d.ts +41 -0
  81. package/lib/types/sharedLiquidity.js +2 -0
  82. package/package.json +1 -1
@@ -0,0 +1,528 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MorphoMarketV1 = void 0;
4
+ const blue_sdk_1 = require("@morpho-org/blue-sdk");
5
+ const blue_sdk_viem_1 = require("@morpho-org/blue-sdk-viem");
6
+ const simulation_sdk_1 = require("@morpho-org/simulation-sdk");
7
+ const actions_1 = require("../../actions");
8
+ const helpers_1 = require("../../helpers");
9
+ const types_1 = require("../../types");
10
+ class MorphoMarketV1 {
11
+ client;
12
+ marketParams;
13
+ chainId;
14
+ constructor(client, marketParams, chainId) {
15
+ this.client = client;
16
+ this.marketParams = marketParams;
17
+ this.chainId = chainId;
18
+ }
19
+ async getMarketData(parameters) {
20
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
21
+ return (0, blue_sdk_viem_1.fetchMarket)(this.marketParams.id, this.client.viemClient, {
22
+ ...parameters,
23
+ chainId: this.chainId,
24
+ deployless: this.client.options.supportDeployless,
25
+ });
26
+ }
27
+ async getPositionData(userAddress, parameters) {
28
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
29
+ return (0, blue_sdk_viem_1.fetchAccrualPosition)(userAddress, this.marketParams.id, this.client.viemClient, {
30
+ ...parameters,
31
+ deployless: this.client.options.supportDeployless,
32
+ chainId: this.chainId,
33
+ });
34
+ }
35
+ supplyCollateral({ amount = 0n, userAddress, nativeAmount, }) {
36
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
37
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, userAddress);
38
+ if (amount < 0n) {
39
+ throw new types_1.NonPositiveAssetAmountError(this.marketParams.collateralToken);
40
+ }
41
+ if (nativeAmount !== undefined && nativeAmount < 0n) {
42
+ throw new types_1.NegativeNativeAmountError(nativeAmount);
43
+ }
44
+ const totalCollateral = amount + (nativeAmount ?? 0n);
45
+ if (totalCollateral === 0n) {
46
+ throw new types_1.ZeroCollateralAmountError(this.marketParams.id);
47
+ }
48
+ if (nativeAmount !== undefined && nativeAmount > 0n) {
49
+ (0, helpers_1.validateNativeCollateral)(this.chainId, this.marketParams.collateralToken);
50
+ }
51
+ return {
52
+ getRequirements: (params) => (0, actions_1.getRequirements)(this.client.viemClient, {
53
+ address: this.marketParams.collateralToken,
54
+ chainId: this.chainId,
55
+ supportSignature: this.client.options.supportSignature,
56
+ supportDeployless: this.client.options.supportDeployless,
57
+ useSimplePermit: params?.useSimplePermit,
58
+ args: { amount, from: userAddress },
59
+ }),
60
+ buildTx: (requirementSignature) => (0, actions_1.marketV1SupplyCollateral)({
61
+ market: {
62
+ chainId: this.chainId,
63
+ marketParams: this.marketParams,
64
+ },
65
+ args: {
66
+ amount,
67
+ nativeAmount,
68
+ onBehalf: userAddress,
69
+ requirementSignature,
70
+ },
71
+ metadata: this.client.options.metadata,
72
+ }),
73
+ };
74
+ }
75
+ borrow({ amount, userAddress, positionData, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, reallocations, }) {
76
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
77
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, userAddress);
78
+ if (amount <= 0n) {
79
+ throw new types_1.NonPositiveBorrowAmountError(this.marketParams.id);
80
+ }
81
+ (0, helpers_1.validateSlippageTolerance)(slippageTolerance);
82
+ if (!positionData) {
83
+ throw new types_1.MissingAccrualPositionError(this.marketParams.id);
84
+ }
85
+ (0, helpers_1.validateAccrualPosition)({
86
+ positionData,
87
+ expectedMarketId: this.marketParams.id,
88
+ expectedUser: userAddress,
89
+ });
90
+ (0, helpers_1.validatePositionHealth)({
91
+ positionData,
92
+ additionalCollateral: 0n,
93
+ borrowAmount: amount,
94
+ marketId: this.marketParams.id,
95
+ lltv: this.marketParams.lltv,
96
+ });
97
+ const minSharePrice = (0, helpers_1.computeMinBorrowSharePrice)({
98
+ borrowAmount: amount,
99
+ market: positionData.market,
100
+ slippageTolerance,
101
+ });
102
+ return {
103
+ getRequirements: async () => {
104
+ const authTx = await (0, actions_1.getMorphoAuthorizationRequirement)({
105
+ viemClient: this.client.viemClient,
106
+ chainId: this.chainId,
107
+ userAddress,
108
+ });
109
+ return authTx ? [authTx] : [];
110
+ },
111
+ buildTx: () => (0, actions_1.marketV1Borrow)({
112
+ market: {
113
+ chainId: this.chainId,
114
+ marketParams: this.marketParams,
115
+ },
116
+ args: {
117
+ amount,
118
+ receiver: userAddress,
119
+ minSharePrice,
120
+ reallocations,
121
+ },
122
+ metadata: this.client.options.metadata,
123
+ }),
124
+ };
125
+ }
126
+ repay(params) {
127
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
128
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, params.userAddress);
129
+ const { userAddress, positionData, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, } = params;
130
+ if ("assets" in params && "shares" in params) {
131
+ throw new types_1.MutuallyExclusiveRepayAmountsError(this.marketParams.id);
132
+ }
133
+ const isSharesMode = "shares" in params;
134
+ if (isSharesMode) {
135
+ if (params.shares <= 0n) {
136
+ throw new types_1.NonPositiveRepayAmountError(this.marketParams.id);
137
+ }
138
+ }
139
+ else {
140
+ if (params.assets <= 0n) {
141
+ throw new types_1.NonPositiveRepayAmountError(this.marketParams.id);
142
+ }
143
+ }
144
+ (0, helpers_1.validateSlippageTolerance)(slippageTolerance);
145
+ if (!positionData) {
146
+ throw new types_1.MissingAccrualPositionError(this.marketParams.id);
147
+ }
148
+ (0, helpers_1.validateAccrualPosition)({
149
+ positionData,
150
+ expectedMarketId: this.marketParams.id,
151
+ expectedUser: userAddress,
152
+ });
153
+ let assets;
154
+ let shares;
155
+ let transferAmount;
156
+ if (isSharesMode) {
157
+ (0, helpers_1.validateRepayShares)({
158
+ positionData,
159
+ repayShares: params.shares,
160
+ marketId: this.marketParams.id,
161
+ });
162
+ assets = 0n;
163
+ shares = params.shares;
164
+ // Add slippage buffer to cover interest accrued between tx construction and execution.
165
+ // Without this, the on-chain repay amount may exceed the pre-transferred ERC20 amount.
166
+ const baseTransferAmount = positionData.market.toBorrowAssets(shares, "Up");
167
+ transferAmount = blue_sdk_1.MathLib.wMulUp(baseTransferAmount, blue_sdk_1.MathLib.WAD + slippageTolerance);
168
+ }
169
+ else {
170
+ (0, helpers_1.validateRepayAmount)({
171
+ positionData,
172
+ repayAssets: params.assets,
173
+ marketId: this.marketParams.id,
174
+ });
175
+ assets = params.assets;
176
+ shares = 0n;
177
+ transferAmount = params.assets;
178
+ }
179
+ const maxSharePrice = (0, helpers_1.computeMaxRepaySharePrice)({
180
+ repayAssets: assets,
181
+ repayShares: shares,
182
+ market: positionData.market,
183
+ slippageTolerance,
184
+ });
185
+ return {
186
+ getRequirements: (reqParams) => (0, actions_1.getRequirements)(this.client.viemClient, {
187
+ address: this.marketParams.loanToken,
188
+ chainId: this.chainId,
189
+ supportSignature: this.client.options.supportSignature,
190
+ supportDeployless: this.client.options.supportDeployless,
191
+ useSimplePermit: reqParams?.useSimplePermit,
192
+ args: { amount: transferAmount, from: userAddress },
193
+ }),
194
+ buildTx: (requirementSignature) => (0, actions_1.marketV1Repay)({
195
+ market: {
196
+ chainId: this.chainId,
197
+ marketParams: this.marketParams,
198
+ },
199
+ args: {
200
+ assets,
201
+ shares,
202
+ transferAmount,
203
+ onBehalf: userAddress,
204
+ receiver: userAddress,
205
+ maxSharePrice,
206
+ requirementSignature,
207
+ },
208
+ metadata: this.client.options.metadata,
209
+ }),
210
+ };
211
+ }
212
+ withdrawCollateral({ userAddress, amount, positionData, }) {
213
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
214
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, userAddress);
215
+ if (amount <= 0n) {
216
+ throw new types_1.NonPositiveWithdrawCollateralAmountError(this.marketParams.id);
217
+ }
218
+ if (!positionData) {
219
+ throw new types_1.MissingAccrualPositionError(this.marketParams.id);
220
+ }
221
+ (0, helpers_1.validateAccrualPosition)({
222
+ positionData,
223
+ expectedMarketId: this.marketParams.id,
224
+ expectedUser: userAddress,
225
+ });
226
+ if (amount > positionData.collateral) {
227
+ throw new types_1.WithdrawExceedsCollateralError({
228
+ withdrawAmount: amount,
229
+ available: positionData.collateral,
230
+ market: positionData.marketId,
231
+ });
232
+ }
233
+ (0, helpers_1.validatePositionHealthAfterWithdraw)({
234
+ positionData,
235
+ withdrawAmount: amount,
236
+ lltv: this.marketParams.lltv,
237
+ marketId: this.marketParams.id,
238
+ });
239
+ return {
240
+ buildTx: () => (0, actions_1.marketV1WithdrawCollateral)({
241
+ market: {
242
+ chainId: this.chainId,
243
+ marketParams: this.marketParams,
244
+ },
245
+ args: {
246
+ amount,
247
+ onBehalf: userAddress,
248
+ receiver: userAddress,
249
+ },
250
+ metadata: this.client.options.metadata,
251
+ }),
252
+ };
253
+ }
254
+ repayWithdrawCollateral(params) {
255
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
256
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, params.userAddress);
257
+ const { userAddress, withdrawAmount, positionData, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, } = params;
258
+ if ("assets" in params && "shares" in params) {
259
+ throw new types_1.MutuallyExclusiveRepayAmountsError(this.marketParams.id);
260
+ }
261
+ const isSharesMode = "shares" in params;
262
+ if (isSharesMode) {
263
+ if (params.shares <= 0n) {
264
+ throw new types_1.NonPositiveRepayAmountError(this.marketParams.id);
265
+ }
266
+ }
267
+ else {
268
+ if (params.assets <= 0n) {
269
+ throw new types_1.NonPositiveRepayAmountError(this.marketParams.id);
270
+ }
271
+ }
272
+ if (withdrawAmount <= 0n) {
273
+ throw new types_1.NonPositiveWithdrawCollateralAmountError(this.marketParams.id);
274
+ }
275
+ (0, helpers_1.validateSlippageTolerance)(slippageTolerance);
276
+ if (!positionData) {
277
+ throw new types_1.MissingAccrualPositionError(this.marketParams.id);
278
+ }
279
+ (0, helpers_1.validateAccrualPosition)({
280
+ positionData,
281
+ expectedMarketId: this.marketParams.id,
282
+ expectedUser: userAddress,
283
+ });
284
+ let assets;
285
+ let shares;
286
+ let transferAmount;
287
+ if (isSharesMode) {
288
+ (0, helpers_1.validateRepayShares)({
289
+ positionData,
290
+ repayShares: params.shares,
291
+ marketId: this.marketParams.id,
292
+ });
293
+ assets = 0n;
294
+ shares = params.shares;
295
+ const baseTransferAmount = positionData.market.toBorrowAssets(shares, "Up");
296
+ transferAmount = blue_sdk_1.MathLib.wMulUp(baseTransferAmount, blue_sdk_1.MathLib.WAD + slippageTolerance);
297
+ }
298
+ else {
299
+ (0, helpers_1.validateRepayAmount)({
300
+ positionData,
301
+ repayAssets: params.assets,
302
+ marketId: this.marketParams.id,
303
+ });
304
+ assets = params.assets;
305
+ shares = 0n;
306
+ transferAmount = params.assets;
307
+ }
308
+ if (withdrawAmount > positionData.collateral) {
309
+ throw new types_1.WithdrawExceedsCollateralError({
310
+ withdrawAmount,
311
+ available: positionData.collateral,
312
+ market: positionData.marketId,
313
+ });
314
+ }
315
+ // Simulate repay to get post-repay position, then validate withdraw health
316
+ const { position: positionAfterRepay } = positionData.repay(assets, shares);
317
+ (0, helpers_1.validatePositionHealthAfterWithdraw)({
318
+ positionData: positionAfterRepay,
319
+ withdrawAmount,
320
+ lltv: this.marketParams.lltv,
321
+ marketId: this.marketParams.id,
322
+ });
323
+ const maxSharePrice = (0, helpers_1.computeMaxRepaySharePrice)({
324
+ repayAssets: assets,
325
+ repayShares: shares,
326
+ market: positionData.market,
327
+ slippageTolerance,
328
+ });
329
+ return {
330
+ getRequirements: async (reqParams) => {
331
+ const [erc20Requirements, authTx] = await Promise.all([
332
+ (0, actions_1.getRequirements)(this.client.viemClient, {
333
+ address: this.marketParams.loanToken,
334
+ chainId: this.chainId,
335
+ supportSignature: this.client.options.supportSignature,
336
+ supportDeployless: this.client.options.supportDeployless,
337
+ useSimplePermit: reqParams?.useSimplePermit,
338
+ args: { amount: transferAmount, from: userAddress },
339
+ }),
340
+ (0, actions_1.getMorphoAuthorizationRequirement)({
341
+ viemClient: this.client.viemClient,
342
+ chainId: this.chainId,
343
+ userAddress,
344
+ }),
345
+ ]);
346
+ return [...erc20Requirements, ...(authTx ? [authTx] : [])];
347
+ },
348
+ buildTx: (requirementSignature) => (0, actions_1.marketV1RepayWithdrawCollateral)({
349
+ market: {
350
+ chainId: this.chainId,
351
+ marketParams: this.marketParams,
352
+ },
353
+ args: {
354
+ assets,
355
+ shares,
356
+ transferAmount,
357
+ withdrawAmount,
358
+ onBehalf: userAddress,
359
+ receiver: userAddress,
360
+ maxSharePrice,
361
+ requirementSignature,
362
+ },
363
+ metadata: this.client.options.metadata,
364
+ }),
365
+ };
366
+ }
367
+ supplyCollateralBorrow({ amount = 0n, userAddress, positionData, borrowAmount, nativeAmount, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, reallocations, }) {
368
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
369
+ (0, helpers_1.validateUserAddress)(this.client.viemClient.account?.address, userAddress);
370
+ if (amount < 0n) {
371
+ throw new types_1.NonPositiveAssetAmountError(this.marketParams.collateralToken);
372
+ }
373
+ if (nativeAmount !== undefined && nativeAmount < 0n) {
374
+ throw new types_1.NegativeNativeAmountError(nativeAmount);
375
+ }
376
+ if (borrowAmount <= 0n) {
377
+ throw new types_1.NonPositiveBorrowAmountError(this.marketParams.id);
378
+ }
379
+ if (!positionData) {
380
+ throw new types_1.MissingAccrualPositionError(this.marketParams.id);
381
+ }
382
+ (0, helpers_1.validateAccrualPosition)({
383
+ positionData,
384
+ expectedMarketId: this.marketParams.id,
385
+ expectedUser: userAddress,
386
+ });
387
+ const totalCollateral = amount + (nativeAmount ?? 0n);
388
+ if (totalCollateral === 0n) {
389
+ throw new types_1.ZeroCollateralAmountError(this.marketParams.id);
390
+ }
391
+ (0, helpers_1.validateSlippageTolerance)(slippageTolerance);
392
+ if (nativeAmount !== undefined && nativeAmount > 0n) {
393
+ (0, helpers_1.validateNativeCollateral)(this.chainId, this.marketParams.collateralToken);
394
+ }
395
+ (0, helpers_1.validatePositionHealth)({
396
+ positionData,
397
+ additionalCollateral: totalCollateral,
398
+ borrowAmount,
399
+ marketId: this.marketParams.id,
400
+ lltv: this.marketParams.lltv,
401
+ });
402
+ const minSharePrice = (0, helpers_1.computeMinBorrowSharePrice)({
403
+ borrowAmount,
404
+ market: positionData.market,
405
+ slippageTolerance,
406
+ });
407
+ return {
408
+ getRequirements: async (params) => {
409
+ const [erc20Requirements, authTx] = await Promise.all([
410
+ (0, actions_1.getRequirements)(this.client.viemClient, {
411
+ address: this.marketParams.collateralToken,
412
+ chainId: this.chainId,
413
+ supportSignature: this.client.options.supportSignature,
414
+ supportDeployless: this.client.options.supportDeployless,
415
+ useSimplePermit: params?.useSimplePermit,
416
+ args: { amount, from: userAddress },
417
+ }),
418
+ (0, actions_1.getMorphoAuthorizationRequirement)({
419
+ viemClient: this.client.viemClient,
420
+ chainId: this.chainId,
421
+ userAddress,
422
+ }),
423
+ ]);
424
+ return [...erc20Requirements, ...(authTx ? [authTx] : [])];
425
+ },
426
+ buildTx: (requirementSignature) => (0, actions_1.marketV1SupplyCollateralBorrow)({
427
+ market: {
428
+ chainId: this.chainId,
429
+ marketParams: this.marketParams,
430
+ },
431
+ args: {
432
+ amount,
433
+ nativeAmount,
434
+ borrowAmount,
435
+ onBehalf: userAddress,
436
+ receiver: userAddress,
437
+ minSharePrice,
438
+ requirementSignature,
439
+ reallocations,
440
+ },
441
+ metadata: this.client.options.metadata,
442
+ }),
443
+ };
444
+ }
445
+ async getReallocationData({ vaultAddresses, market, block, }) {
446
+ (0, helpers_1.validateChainId)(this.client.viemClient.chain?.id, this.chainId);
447
+ if (market.id !== this.marketParams.id) {
448
+ throw new types_1.MarketIdMismatchError(market.id, this.marketParams.id);
449
+ }
450
+ const client = this.client.viemClient;
451
+ const fetchParams = {
452
+ blockNumber: block.number,
453
+ chainId: this.chainId,
454
+ deployless: this.client.options.supportDeployless,
455
+ };
456
+ // Phase 1: Fetch all vaults in parallel to get their withdrawQueues.
457
+ const vaults = await Promise.all(vaultAddresses.map((addr) => (0, blue_sdk_viem_1.fetchVault)(addr, client, fetchParams)));
458
+ // Collect unique market IDs from all vault withdrawQueues + target market.
459
+ const targetMarketId = this.marketParams.id;
460
+ const allMarketIds = new Set([targetMarketId]);
461
+ const vaultMarketPairs = [];
462
+ for (const vault of vaults) {
463
+ // Always include target market pair so its config/position is fetched
464
+ // even when the target market is only in the vault's supplyQueue.
465
+ vaultMarketPairs.push({ vault: vault.address, marketId: targetMarketId });
466
+ for (const mid of vault.withdrawQueue) {
467
+ allMarketIds.add(mid);
468
+ if (mid !== targetMarketId) {
469
+ vaultMarketPairs.push({ vault: vault.address, marketId: mid });
470
+ }
471
+ }
472
+ }
473
+ // Phase 2: Fetch all source markets, vault configs, and positions in parallel.
474
+ const sourceMarketIds = [...allMarketIds].filter((mid) => mid !== targetMarketId);
475
+ const loanToken = market.params.loanToken;
476
+ const [markets, configs, positions, holdings] = await Promise.all([
477
+ Promise.all(sourceMarketIds.map((mid) => (0, blue_sdk_viem_1.fetchMarket)(mid, client, fetchParams))),
478
+ Promise.all(vaultMarketPairs.map(({ vault, marketId: mid }) => (0, blue_sdk_viem_1.fetchVaultMarketConfig)(vault, mid, client, fetchParams).then((config) => ({ vault, mid, config })))),
479
+ Promise.all(vaultMarketPairs.map(({ vault, marketId: mid }) => (0, blue_sdk_viem_1.fetchPosition)(vault, mid, client, fetchParams).then((position) => ({
480
+ vault,
481
+ mid,
482
+ position,
483
+ })))),
484
+ Promise.all(vaultAddresses.map((addr) => (0, blue_sdk_viem_1.fetchHolding)(addr, loanToken, client, fetchParams))),
485
+ ]);
486
+ // Assemble records for SimulationState.
487
+ const marketsRecord = {
488
+ [targetMarketId]: market,
489
+ };
490
+ for (const m of markets) {
491
+ marketsRecord[m.id] = m;
492
+ }
493
+ const vaultsRecord = {};
494
+ for (const v of vaults) {
495
+ vaultsRecord[v.address] = v;
496
+ }
497
+ const vaultMarketConfigsRecord = {};
498
+ for (const { vault, mid, config } of configs) {
499
+ (vaultMarketConfigsRecord[vault] ??= {})[mid] = config;
500
+ }
501
+ const positionsRecord = {};
502
+ for (const { vault, mid, position } of positions) {
503
+ (positionsRecord[vault] ??= {})[mid] = position;
504
+ }
505
+ const holdingsRecord = {};
506
+ for (const holding of holdings) {
507
+ (holdingsRecord[holding.user] ??= {})[holding.token] = holding;
508
+ }
509
+ return new simulation_sdk_1.SimulationState({
510
+ chainId: this.chainId,
511
+ block,
512
+ markets: marketsRecord,
513
+ vaults: vaultsRecord,
514
+ vaultMarketConfigs: vaultMarketConfigsRecord,
515
+ positions: positionsRecord,
516
+ holdings: holdingsRecord,
517
+ });
518
+ }
519
+ getReallocations({ reallocationData, borrowAmount, options, }) {
520
+ return (0, helpers_1.computeReallocations)({
521
+ reallocationData,
522
+ marketId: this.marketParams.id,
523
+ borrowAmount,
524
+ options: { enabled: true, ...options },
525
+ });
526
+ }
527
+ }
528
+ exports.MorphoMarketV1 = MorphoMarketV1;
@@ -0,0 +1 @@
1
+ export * from "./vaultV1";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./vaultV1"), exports);
@@ -0,0 +1,95 @@
1
+ import { type AccrualVault } from "@morpho-org/blue-sdk";
2
+ import { fetchAccrualVault } from "@morpho-org/blue-sdk-viem";
3
+ import { type Address } from "viem";
4
+ import { type DepositAmountArgs, type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV1DepositAction, type VaultV1RedeemAction, type VaultV1WithdrawAction } from "../../types";
5
+ import type { FetchParameters } from "../../types/data";
6
+ export interface VaultV1Actions {
7
+ /**
8
+ * Fetches the latest vault data with accrued interest.
9
+ *
10
+ * @param {FetchParameters} [parameters] - Optional fetch parameters (block number, state overrides, etc.).
11
+ * @returns {Promise<Awaited<ReturnType<typeof fetchAccrualVault>>>} The latest accrued vault data.
12
+ */
13
+ getData: (parameters?: FetchParameters) => Promise<Awaited<ReturnType<typeof fetchAccrualVault>>>;
14
+ /**
15
+ * Prepares a deposit into a VaultV1 (MetaMorpho) contract.
16
+ *
17
+ * Uses pre-fetched accrual vault data to compute `maxSharePrice` with slippage tolerance,
18
+ * then returns `buildTx` and `getRequirements` for lazy evaluation.
19
+ *
20
+ * @param {Object} params - The deposit parameters.
21
+ * @param {bigint} params.amount - Amount of assets to deposit.
22
+ * @param {Address} params.userAddress - User address initiating the deposit.
23
+ * @param {AccrualVault} params.accrualVault - Pre-fetched vault data with asset address and share conversion.
24
+ * @param {bigint} [params.slippageTolerance=DEFAULT_SLIPPAGE_TOLERANCE] - Slippage tolerance (default 0.03%, max 10%).
25
+ * @param {bigint} [params.nativeAmount] - Amount of native ETH to wrap into WETH. Vault asset must be wNative.
26
+ * @returns {Object} Object with `buildTx` and `getRequirements`.
27
+ */
28
+ deposit: (params: {
29
+ userAddress: Address;
30
+ accrualVault: AccrualVault;
31
+ slippageTolerance?: bigint;
32
+ } & DepositAmountArgs) => {
33
+ buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV1DepositAction>>;
34
+ getRequirements: (params?: {
35
+ useSimplePermit?: boolean;
36
+ }) => Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>;
37
+ };
38
+ /**
39
+ * Prepares a withdraw from a VaultV1 (MetaMorpho) contract.
40
+ *
41
+ * @param {Object} params - The withdraw parameters.
42
+ * @param {bigint} params.amount - Amount of assets to withdraw.
43
+ * @param {Address} params.userAddress - User address initiating the withdraw.
44
+ * @returns {Object} Object with `buildTx`.
45
+ */
46
+ withdraw: (params: {
47
+ amount: bigint;
48
+ userAddress: Address;
49
+ }) => {
50
+ buildTx: () => Readonly<Transaction<VaultV1WithdrawAction>>;
51
+ };
52
+ /**
53
+ * Prepares a redeem from a VaultV1 (MetaMorpho) contract.
54
+ *
55
+ * @param {Object} params - The redeem parameters.
56
+ * @param {bigint} params.shares - Amount of shares to redeem.
57
+ * @param {Address} params.userAddress - User address initiating the redeem.
58
+ * @returns {Object} Object with `buildTx`.
59
+ */
60
+ redeem: (params: {
61
+ shares: bigint;
62
+ userAddress: Address;
63
+ }) => {
64
+ buildTx: () => Readonly<Transaction<VaultV1RedeemAction>>;
65
+ };
66
+ }
67
+ export declare class MorphoVaultV1 implements VaultV1Actions {
68
+ private readonly client;
69
+ private readonly vault;
70
+ private readonly chainId;
71
+ constructor(client: MorphoClientType, vault: Address, chainId: number);
72
+ getData(parameters?: FetchParameters): Promise<AccrualVault>;
73
+ deposit({ amount, userAddress, accrualVault, slippageTolerance, nativeAmount, }: {
74
+ userAddress: Address;
75
+ accrualVault: AccrualVault;
76
+ slippageTolerance?: bigint;
77
+ } & DepositAmountArgs): {
78
+ getRequirements: (params?: {
79
+ useSimplePermit?: boolean;
80
+ }) => Promise<(Requirement | Readonly<Transaction<ERC20ApprovalAction>>)[]>;
81
+ buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV1DepositAction>>;
82
+ };
83
+ withdraw({ amount, userAddress }: {
84
+ amount: bigint;
85
+ userAddress: Address;
86
+ }): {
87
+ buildTx: () => Readonly<Transaction<VaultV1WithdrawAction>>;
88
+ };
89
+ redeem({ shares, userAddress }: {
90
+ shares: bigint;
91
+ userAddress: Address;
92
+ }): {
93
+ buildTx: () => Readonly<Transaction<VaultV1RedeemAction>>;
94
+ };
95
+ }