@lit-protocol/vincent-ability-morpho 0.0.7-mma

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 (33) hide show
  1. package/CONTRIBUTING.md +90 -0
  2. package/README.md +136 -0
  3. package/dist/CONTRIBUTING.md +90 -0
  4. package/dist/README.md +136 -0
  5. package/dist/package.json +34 -0
  6. package/dist/src/generated/lit-action.js +9 -0
  7. package/dist/src/generated/vincent-ability-metadata.json +3 -0
  8. package/dist/src/generated/vincent-bundled-ability.d.ts +98 -0
  9. package/dist/src/generated/vincent-bundled-ability.d.ts.map +1 -0
  10. package/dist/src/generated/vincent-bundled-ability.js +15 -0
  11. package/dist/src/generated/vincent-bundled-ability.js.map +1 -0
  12. package/dist/src/generated/vincent-bundled-ability.ts +13 -0
  13. package/dist/src/index.d.ts +3 -0
  14. package/dist/src/index.d.ts.map +1 -0
  15. package/dist/src/index.js +8 -0
  16. package/dist/src/index.js.map +1 -0
  17. package/dist/src/lib/helpers/index.d.ts +561 -0
  18. package/dist/src/lib/helpers/index.d.ts.map +1 -0
  19. package/dist/src/lib/helpers/index.js +1123 -0
  20. package/dist/src/lib/helpers/index.js.map +1 -0
  21. package/dist/src/lib/lit-action.d.ts +2 -0
  22. package/dist/src/lib/lit-action.d.ts.map +1 -0
  23. package/dist/src/lib/lit-action.js +16 -0
  24. package/dist/src/lib/lit-action.js.map +1 -0
  25. package/dist/src/lib/schemas.d.ts +125 -0
  26. package/dist/src/lib/schemas.d.ts.map +1 -0
  27. package/dist/src/lib/schemas.js +109 -0
  28. package/dist/src/lib/schemas.js.map +1 -0
  29. package/dist/src/lib/vincent-ability.d.ts +96 -0
  30. package/dist/src/lib/vincent-ability.d.ts.map +1 -0
  31. package/dist/src/lib/vincent-ability.js +378 -0
  32. package/dist/src/lib/vincent-ability.js.map +1 -0
  33. package/package.json +33 -0
@@ -0,0 +1,1123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.morphoVaultClient = exports.MorphoVaultClient = exports.VAULT_FILTER_PRESETS = exports.ERC20_ABI = exports.MORPHO_MARKET_ABI = exports.ERC4626_VAULT_ABI = exports.CHAIN_IDS = exports.SUPPORTED_CHAINS = exports.WELL_KNOWN_TOKENS = void 0;
4
+ exports.getTokenAddresses = getTokenAddresses;
5
+ exports.getTokenAddress = getTokenAddress;
6
+ exports.isSupportedChain = isSupportedChain;
7
+ exports.getSupportedChainIds = getSupportedChainIds;
8
+ exports.getChainName = getChainName;
9
+ exports.isValidAddress = isValidAddress;
10
+ exports.parseAmount = parseAmount;
11
+ exports.formatAmount = formatAmount;
12
+ exports.validateOperationRequirements = validateOperationRequirements;
13
+ exports.getBestVaultsForAsset = getBestVaultsForAsset;
14
+ exports.getTopVaultsByNetApy = getTopVaultsByNetApy;
15
+ exports.getTopVaultsByTvl = getTopVaultsByTvl;
16
+ exports.searchVaults = searchVaults;
17
+ exports.getVaultsByPreset = getVaultsByPreset;
18
+ exports.getVaults = getVaults;
19
+ exports.getSupportedChainsWithVaults = getSupportedChainsWithVaults;
20
+ exports.getVaultDiscoverySummary = getVaultDiscoverySummary;
21
+ exports.executeMorphoMarketOperation = executeMorphoMarketOperation;
22
+ exports.executeMorphoVaultOperation = executeMorphoVaultOperation;
23
+ const vincent_scaffold_sdk_1 = require("@lit-protocol/vincent-scaffold-sdk");
24
+ const ethers_1 = require("ethers");
25
+ /**
26
+ * Well-known token addresses across different chains
27
+ * Using official Circle USDC and canonical WETH addresses
28
+ */
29
+ exports.WELL_KNOWN_TOKENS = {
30
+ // Ethereum mainnet
31
+ 1: {
32
+ USDC: '0xA0b86991c6218A36c1D19D4a2e9Eb0cE3606eB48', // Circle USDC
33
+ WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Canonical WETH
34
+ USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // Tether USDT
35
+ },
36
+ // Base
37
+ 8453: {
38
+ USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // Native USDC on Base
39
+ WETH: '0x4200000000000000000000000000000000000006', // WETH on Base
40
+ USDT: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2', // USDT on Base
41
+ },
42
+ // Arbitrum One
43
+ 42161: {
44
+ USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // Native USDC on Arbitrum
45
+ WETH: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // WETH on Arbitrum
46
+ USDT: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT on Arbitrum
47
+ },
48
+ // Optimism
49
+ 10: {
50
+ USDC: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // Native USDC on Optimism
51
+ WETH: '0x4200000000000000000000000000000000000006', // WETH on Optimism
52
+ USDT: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', // USDT on Optimism
53
+ },
54
+ // Polygon
55
+ 137: {
56
+ USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', // Native USDC on Polygon
57
+ WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', // WETH on Polygon
58
+ USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // USDT on Polygon
59
+ },
60
+ // Sepolia testnet
61
+ 11155111: {
62
+ USDC: '0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8', // Test USDC on Sepolia
63
+ WETH: '0xC558DBdd856501FCd9aaF1E62eae57A9F0629a3c', // Test WETH on Sepolia
64
+ USDT: '0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0', // Test USDT on Sepolia
65
+ },
66
+ };
67
+ /**
68
+ * Supported chain IDs and their names
69
+ */
70
+ exports.SUPPORTED_CHAINS = {
71
+ 1: 'ethereum',
72
+ 8453: 'base',
73
+ 42161: 'arbitrum',
74
+ 10: 'optimism',
75
+ 137: 'polygon',
76
+ 11155111: 'sepolia',
77
+ };
78
+ /**
79
+ * Chain names to IDs mapping for backwards compatibility
80
+ */
81
+ exports.CHAIN_IDS = {
82
+ ethereum: 1,
83
+ base: 8453,
84
+ arbitrum: 42161,
85
+ optimism: 10,
86
+ polygon: 137,
87
+ sepolia: 11155111,
88
+ };
89
+ /**
90
+ * ERC4626 Vault ABI - Essential methods for Morpho vaults
91
+ */
92
+ exports.ERC4626_VAULT_ABI = [
93
+ // Deposit
94
+ {
95
+ inputs: [
96
+ { internalType: 'uint256', name: 'assets', type: 'uint256' },
97
+ { internalType: 'address', name: 'receiver', type: 'address' },
98
+ ],
99
+ name: 'deposit',
100
+ outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],
101
+ stateMutability: 'nonpayable',
102
+ type: 'function',
103
+ },
104
+ // Withdraw
105
+ {
106
+ inputs: [
107
+ { internalType: 'uint256', name: 'assets', type: 'uint256' },
108
+ { internalType: 'address', name: 'receiver', type: 'address' },
109
+ { internalType: 'address', name: 'owner', type: 'address' },
110
+ ],
111
+ name: 'withdraw',
112
+ outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],
113
+ stateMutability: 'nonpayable',
114
+ type: 'function',
115
+ },
116
+ // Redeem
117
+ {
118
+ inputs: [
119
+ { internalType: 'uint256', name: 'shares', type: 'uint256' },
120
+ { internalType: 'address', name: 'receiver', type: 'address' },
121
+ { internalType: 'address', name: 'owner', type: 'address' },
122
+ ],
123
+ name: 'redeem',
124
+ outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }],
125
+ stateMutability: 'nonpayable',
126
+ type: 'function',
127
+ },
128
+ // Asset (underlying token address)
129
+ {
130
+ inputs: [],
131
+ name: 'asset',
132
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
133
+ stateMutability: 'view',
134
+ type: 'function',
135
+ },
136
+ // Balance of shares
137
+ {
138
+ inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
139
+ name: 'balanceOf',
140
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
141
+ stateMutability: 'view',
142
+ type: 'function',
143
+ },
144
+ // Convert assets to shares
145
+ {
146
+ inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }],
147
+ name: 'convertToShares',
148
+ outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],
149
+ stateMutability: 'view',
150
+ type: 'function',
151
+ },
152
+ // Convert shares to assets
153
+ {
154
+ inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],
155
+ name: 'convertToAssets',
156
+ outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }],
157
+ stateMutability: 'view',
158
+ type: 'function',
159
+ },
160
+ // Total assets managed by the vault
161
+ {
162
+ inputs: [],
163
+ name: 'totalAssets',
164
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
165
+ stateMutability: 'view',
166
+ type: 'function',
167
+ },
168
+ {
169
+ inputs: [],
170
+ name: 'decimals',
171
+ outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }],
172
+ stateMutability: 'view',
173
+ type: 'function',
174
+ },
175
+ ];
176
+ /**
177
+ * Morpho Market ABI - Essential methods for supply and withdraw operations
178
+ */
179
+ exports.MORPHO_MARKET_ABI = [
180
+ // Supply
181
+ {
182
+ inputs: [
183
+ {
184
+ components: [
185
+ { internalType: 'address', name: 'loanToken', type: 'address' },
186
+ { internalType: 'address', name: 'collateralToken', type: 'address' },
187
+ { internalType: 'address', name: 'oracle', type: 'address' },
188
+ { internalType: 'address', name: 'irm', type: 'address' },
189
+ { internalType: 'uint256', name: 'lltv', type: 'uint256' },
190
+ ],
191
+ internalType: 'struct MarketParams',
192
+ name: 'marketParams',
193
+ type: 'tuple',
194
+ },
195
+ { internalType: 'uint256', name: 'assets', type: 'uint256' },
196
+ { internalType: 'uint256', name: 'shares', type: 'uint256' },
197
+ { internalType: 'address', name: 'onBehalf', type: 'address' },
198
+ { internalType: 'bytes', name: 'data', type: 'bytes' },
199
+ ],
200
+ name: 'supply',
201
+ outputs: [
202
+ { internalType: 'uint256', name: 'assetsSupplied', type: 'uint256' },
203
+ { internalType: 'uint256', name: 'sharesSupplied', type: 'uint256' },
204
+ ],
205
+ stateMutability: 'nonpayable',
206
+ type: 'function',
207
+ },
208
+ // Withdraw Collateral
209
+ {
210
+ inputs: [
211
+ {
212
+ components: [
213
+ { internalType: 'address', name: 'loanToken', type: 'address' },
214
+ { internalType: 'address', name: 'collateralToken', type: 'address' },
215
+ { internalType: 'address', name: 'oracle', type: 'address' },
216
+ { internalType: 'address', name: 'irm', type: 'address' },
217
+ { internalType: 'uint256', name: 'lltv', type: 'uint256' },
218
+ ],
219
+ internalType: 'struct MarketParams',
220
+ name: 'marketParams',
221
+ type: 'tuple',
222
+ },
223
+ { internalType: 'uint256', name: 'assets', type: 'uint256' },
224
+ { internalType: 'address', name: 'onBehalf', type: 'address' },
225
+ { internalType: 'address', name: 'receiver', type: 'address' },
226
+ ],
227
+ name: 'withdrawCollateral',
228
+ outputs: [],
229
+ stateMutability: 'nonpayable',
230
+ type: 'function',
231
+ },
232
+ // Position (to check collateral balance)
233
+ {
234
+ inputs: [
235
+ { internalType: 'bytes32', name: 'id', type: 'bytes32' },
236
+ { internalType: 'address', name: 'user', type: 'address' },
237
+ ],
238
+ name: 'position',
239
+ outputs: [
240
+ { internalType: 'uint256', name: 'supplyShares', type: 'uint256' },
241
+ { internalType: 'uint128', name: 'borrowShares', type: 'uint128' },
242
+ { internalType: 'uint128', name: 'collateral', type: 'uint128' },
243
+ ],
244
+ stateMutability: 'view',
245
+ type: 'function',
246
+ },
247
+ // Market (to check market info)
248
+ {
249
+ inputs: [{ internalType: 'bytes32', name: 'id', type: 'bytes32' }],
250
+ name: 'market',
251
+ outputs: [
252
+ { internalType: 'uint128', name: 'totalSupplyAssets', type: 'uint128' },
253
+ { internalType: 'uint128', name: 'totalSupplyShares', type: 'uint128' },
254
+ { internalType: 'uint128', name: 'totalBorrowAssets', type: 'uint128' },
255
+ { internalType: 'uint128', name: 'totalBorrowShares', type: 'uint128' },
256
+ { internalType: 'uint128', name: 'lastUpdate', type: 'uint128' },
257
+ { internalType: 'uint128', name: 'fee', type: 'uint128' },
258
+ ],
259
+ stateMutability: 'view',
260
+ type: 'function',
261
+ },
262
+ // IdToMarketParams (to get market params from ID)
263
+ {
264
+ inputs: [{ internalType: 'bytes32', name: 'id', type: 'bytes32' }],
265
+ name: 'idToMarketParams',
266
+ outputs: [
267
+ { internalType: 'address', name: 'loanToken', type: 'address' },
268
+ { internalType: 'address', name: 'collateralToken', type: 'address' },
269
+ { internalType: 'address', name: 'oracle', type: 'address' },
270
+ { internalType: 'address', name: 'irm', type: 'address' },
271
+ { internalType: 'uint256', name: 'lltv', type: 'uint256' },
272
+ ],
273
+ stateMutability: 'view',
274
+ type: 'function',
275
+ },
276
+ ];
277
+ /**
278
+ * ERC20 Token ABI - Essential methods only
279
+ */
280
+ exports.ERC20_ABI = [
281
+ {
282
+ inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
283
+ name: 'balanceOf',
284
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
285
+ stateMutability: 'view',
286
+ type: 'function',
287
+ },
288
+ {
289
+ inputs: [
290
+ { internalType: 'address', name: 'owner', type: 'address' },
291
+ { internalType: 'address', name: 'spender', type: 'address' },
292
+ ],
293
+ name: 'allowance',
294
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
295
+ stateMutability: 'view',
296
+ type: 'function',
297
+ },
298
+ {
299
+ inputs: [
300
+ { internalType: 'address', name: 'spender', type: 'address' },
301
+ { internalType: 'uint256', name: 'amount', type: 'uint256' },
302
+ ],
303
+ name: 'approve',
304
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
305
+ stateMutability: 'nonpayable',
306
+ type: 'function',
307
+ },
308
+ {
309
+ inputs: [],
310
+ name: 'decimals',
311
+ outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }],
312
+ stateMutability: 'view',
313
+ type: 'function',
314
+ },
315
+ ];
316
+ /**
317
+ * Pre-configured filter presets for common use cases
318
+ */
319
+ exports.VAULT_FILTER_PRESETS = {
320
+ highYield: {
321
+ minNetApy: 0.08,
322
+ minTvl: 1000000,
323
+ sortBy: 'netApy',
324
+ sortOrder: 'desc',
325
+ excludeIdle: true,
326
+ limit: 10,
327
+ },
328
+ stable: {
329
+ minTvl: 5000000,
330
+ maxNetApy: 0.15,
331
+ whitelistedOnly: true,
332
+ sortBy: 'totalAssetsUsd',
333
+ sortOrder: 'desc',
334
+ excludeIdle: true,
335
+ limit: 10,
336
+ },
337
+ highTvl: {
338
+ minTvl: 10000000,
339
+ sortBy: 'totalAssetsUsd',
340
+ sortOrder: 'desc',
341
+ excludeIdle: true,
342
+ limit: 20,
343
+ },
344
+ };
345
+ /**
346
+ * Get well-known token addresses for a specific chain
347
+ */
348
+ function getTokenAddresses(chainId) {
349
+ if (!(chainId in exports.WELL_KNOWN_TOKENS)) {
350
+ throw new Error(`Unsupported chain ID: ${chainId}. Supported chains: ${Object.keys(exports.WELL_KNOWN_TOKENS).join(', ')}`);
351
+ }
352
+ return exports.WELL_KNOWN_TOKENS[chainId];
353
+ }
354
+ /**
355
+ * Get token address for a specific token symbol and chain
356
+ */
357
+ function getTokenAddress(symbol, chainId) {
358
+ const tokens = getTokenAddresses(chainId);
359
+ const upperSymbol = symbol.toUpperCase();
360
+ if (!(upperSymbol in tokens)) {
361
+ throw new Error(`Token ${symbol} not found on chain ${chainId}. Available tokens: ${Object.keys(tokens).join(', ')}`);
362
+ }
363
+ return tokens[upperSymbol];
364
+ }
365
+ /**
366
+ * Check if a chain is supported by Morpho
367
+ */
368
+ function isSupportedChain(chainId) {
369
+ return chainId in exports.WELL_KNOWN_TOKENS;
370
+ }
371
+ /**
372
+ * Get all supported chain IDs
373
+ */
374
+ function getSupportedChainIds() {
375
+ return Object.keys(exports.WELL_KNOWN_TOKENS).map(Number);
376
+ }
377
+ /**
378
+ * Get chain name from chain ID
379
+ */
380
+ function getChainName(chainId) {
381
+ return exports.SUPPORTED_CHAINS[chainId] || `chain-${chainId}`;
382
+ }
383
+ /**
384
+ * Utility function to validate Ethereum address
385
+ */
386
+ function isValidAddress(address) {
387
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
388
+ }
389
+ /**
390
+ * Utility function to parse amount with decimals
391
+ */
392
+ function parseAmount(amount, decimals = 18) {
393
+ return ethers_1.ethers.utils.parseUnits(amount, decimals).toString();
394
+ }
395
+ /**
396
+ * Utility function to format amount from wei
397
+ */
398
+ function formatAmount(amount, decimals = 18) {
399
+ return ethers_1.ethers.utils.formatUnits(amount, decimals);
400
+ }
401
+ /**
402
+ * Validate operation-specific requirements for Morpho vaults and markets
403
+ */
404
+ async function validateOperationRequirements(operation, userBalance, allowance, vaultShares, convertedAmount, collateralBalance) {
405
+ const userBalanceBN = BigInt(userBalance);
406
+ const allowanceBN = BigInt(allowance);
407
+ const vaultSharesBN = BigInt(vaultShares);
408
+ const convertedAmountBN = BigInt(convertedAmount);
409
+ const collateralBalanceBN = collateralBalance ? BigInt(collateralBalance) : 0n;
410
+ switch (operation) {
411
+ case 'vault_deposit':
412
+ // Check if user has enough balance
413
+ if (userBalanceBN < convertedAmountBN) {
414
+ return {
415
+ valid: false,
416
+ error: `Insufficient balance for ${operation} operation. You have ${userBalance} and need ${convertedAmount}`,
417
+ };
418
+ }
419
+ // Check if user has approved vault to spend tokens
420
+ if (allowanceBN < convertedAmountBN) {
421
+ return {
422
+ valid: false,
423
+ error: `Insufficient allowance for ${operation} operation. Please approve vault to spend your tokens first. You have ${allowance} and need ${convertedAmount}`,
424
+ };
425
+ }
426
+ break;
427
+ case 'vault_withdraw':
428
+ // For withdraw, we need to check if user has enough vault shares
429
+ if (vaultSharesBN === 0n) {
430
+ return {
431
+ valid: false,
432
+ error: 'No vault shares available for withdrawal',
433
+ };
434
+ }
435
+ // Note: We'll need to convert the amount to shares in the actual implementation
436
+ break;
437
+ case 'vault_redeem':
438
+ // For redeem, we need to check if user has enough vault shares
439
+ if (vaultSharesBN === 0n) {
440
+ return {
441
+ valid: false,
442
+ error: 'No vault shares available for redeem',
443
+ };
444
+ }
445
+ // For redeem, the amount is in shares, so check directly
446
+ if (vaultSharesBN < convertedAmountBN) {
447
+ return {
448
+ valid: false,
449
+ error: `Insufficient vault shares for redeem operation. You have ${vaultShares} shares and need ${convertedAmount} shares`,
450
+ };
451
+ }
452
+ break;
453
+ case 'market_supply':
454
+ // Check if user has enough balance
455
+ if (userBalanceBN < convertedAmountBN) {
456
+ return {
457
+ valid: false,
458
+ error: `Insufficient balance for market supply operation. You have ${userBalance} and need ${convertedAmount}`,
459
+ };
460
+ }
461
+ // Check if user has approved market to spend tokens
462
+ if (allowanceBN < convertedAmountBN) {
463
+ return {
464
+ valid: false,
465
+ error: `Insufficient allowance for market supply operation. Please approve market to spend your tokens first. You have ${allowance} and need ${convertedAmount}`,
466
+ };
467
+ }
468
+ break;
469
+ case 'market_withdrawCollateral':
470
+ // Check if user has enough collateral balance
471
+ if (collateralBalanceBN < convertedAmountBN) {
472
+ return {
473
+ valid: false,
474
+ error: `Insufficient collateral balance for withdrawal. You have ${collateralBalance} and need ${convertedAmount}`,
475
+ };
476
+ }
477
+ break;
478
+ default:
479
+ return { valid: false, error: `Unsupported operation: ${operation}` };
480
+ }
481
+ return { valid: true };
482
+ }
483
+ /**
484
+ * Morpho GraphQL API Client
485
+ */
486
+ class MorphoVaultClient {
487
+ apiUrl = 'https://blue-api.morpho.org/graphql';
488
+ /**
489
+ * Fetch vault data from Morpho GraphQL API
490
+ */
491
+ async fetchVaultData(query, variables) {
492
+ try {
493
+ // console.log("fetchVaultData", query, variables);
494
+ const response = await fetch(this.apiUrl, {
495
+ method: 'POST',
496
+ headers: {
497
+ 'Content-Type': 'application/json',
498
+ },
499
+ body: JSON.stringify({
500
+ query,
501
+ variables,
502
+ }),
503
+ });
504
+ if (!response.ok) {
505
+ const body = await response.text();
506
+ throw new Error(`HTTP error! status: ${response.status} and body: ${body}`);
507
+ }
508
+ const data = await response.json();
509
+ if (data.errors) {
510
+ throw new Error(`GraphQL error: ${data.errors.map((e) => e.message).join(', ')}`);
511
+ }
512
+ return data.data;
513
+ }
514
+ catch (error) {
515
+ console.error('Failed to fetch vault data:', error);
516
+ throw error;
517
+ }
518
+ }
519
+ /**
520
+ * Get all vaults with comprehensive information
521
+ * Now uses proper server-side filtering via GraphQL VaultFilters
522
+ */
523
+ async getAllVaults(options = {}) {
524
+ // Build GraphQL where clause from options
525
+ const whereClause = this.buildVaultFilters(options);
526
+ const query = `
527
+ query GetAllVaults($first: Int, $orderBy: VaultOrderBy, $orderDirection: OrderDirection, $where: VaultFilters) {
528
+ vaults(first: $first, orderBy: $orderBy, orderDirection: $orderDirection, where: $where) {
529
+ items {
530
+ address
531
+ name
532
+ symbol
533
+ whitelisted
534
+ creationTimestamp
535
+ asset {
536
+ address
537
+ symbol
538
+ name
539
+ decimals
540
+ }
541
+ chain {
542
+ id
543
+ network
544
+ }
545
+ state {
546
+ apy
547
+ netApy
548
+ totalAssets
549
+ totalAssetsUsd
550
+ fee
551
+ rewards {
552
+ asset {
553
+ address
554
+ symbol
555
+ }
556
+ supplyApr
557
+ yearlySupplyTokens
558
+ }
559
+ }
560
+ }
561
+ }
562
+ }
563
+ `;
564
+ // Fetch more results than requested to account for client-side filtering
565
+ // If excludeIdle is true, we might need to filter some out, so fetch extra
566
+ // But never exceed 1000 (GraphQL API limit)
567
+ const calculateFetchLimit = (requestedLimit) => {
568
+ if (!requestedLimit)
569
+ return 100; // Default limit
570
+ // Always cap at 1000 to respect GraphQL API limits
571
+ const cappedLimit = Math.min(requestedLimit, 1000);
572
+ if (options.excludeIdle) {
573
+ // For excludeIdle filtering, fetch extra but never exceed 1000
574
+ return Math.max(cappedLimit, 1000);
575
+ }
576
+ // No client-side filtering, use requested limit (capped at 1000)
577
+ return cappedLimit;
578
+ };
579
+ const fetchLimit = calculateFetchLimit(options.limit);
580
+ const variables = {
581
+ first: fetchLimit,
582
+ orderBy: this.mapSortBy(options.sortBy || 'totalAssetsUsd'),
583
+ orderDirection: options.sortOrder === 'asc' ? 'Asc' : 'Desc',
584
+ where: whereClause,
585
+ };
586
+ const data = await this.fetchVaultData(query, variables);
587
+ const vaults = data.vaults.items.map((vault) => this.mapVaultData(vault));
588
+ // console.log("vaults after server-side filtering", vaults.length);
589
+ // Apply only remaining client-side filters not supported by GraphQL
590
+ const filtered = this.applyRemainingClientFilters(vaults, options);
591
+ // console.log("vaults after additional client filtering", filtered.length);
592
+ // Apply the limit AFTER client-side filtering to ensure we get the expected number of results
593
+ const finalResults = options.limit ? filtered.slice(0, options.limit) : filtered;
594
+ // Log a warning if we couldn't fetch enough results due to API limits
595
+ if (options.limit && options.limit > 1000 && finalResults.length < options.limit) {
596
+ console.warn(`Warning: Requested ${options.limit} vaults but GraphQL API limit is 1000. Got ${finalResults.length} results.`);
597
+ }
598
+ return finalResults;
599
+ }
600
+ /**
601
+ * Unified function to get vaults with flexible filtering
602
+ * Supports filtering by asset, chain, and all other options
603
+ */
604
+ async getVaults(options = {}) {
605
+ // If specific asset or chain filters are provided, enhance the options
606
+ const enhancedOptions = { ...options };
607
+ // Handle chain filtering - support both chainId and chain name/ID
608
+ if (options.chainId) {
609
+ enhancedOptions.chain = options.chainId;
610
+ }
611
+ return this.getAllVaults(enhancedOptions);
612
+ }
613
+ /**
614
+ * Get top vaults by APY
615
+ */
616
+ async getTopVaultsByNetApy(limit = 10, minTvl = 0) {
617
+ return this.getAllVaults({
618
+ sortBy: 'netApy',
619
+ sortOrder: 'desc',
620
+ limit,
621
+ minTvl,
622
+ excludeIdle: true,
623
+ });
624
+ }
625
+ /**
626
+ * Get top vaults by TVL
627
+ */
628
+ async getTopVaultsByTvl(limit = 10) {
629
+ return this.getAllVaults({
630
+ sortBy: 'totalAssetsUsd',
631
+ sortOrder: 'desc',
632
+ limit,
633
+ excludeIdle: true,
634
+ });
635
+ }
636
+ /**
637
+ * Search vaults by name, symbol, or asset
638
+ */
639
+ async searchVaults(searchOptions) {
640
+ const allVaults = await this.getAllVaults({ limit: 500 }); // Reduced to avoid GraphQL limit issues
641
+ if (!searchOptions.query) {
642
+ return allVaults.slice(0, searchOptions.limit || 50);
643
+ }
644
+ const query = searchOptions.query.toLowerCase();
645
+ const filtered = allVaults.filter((vault) => vault.name.toLowerCase().includes(query) ||
646
+ vault.symbol.toLowerCase().includes(query) ||
647
+ vault.asset.symbol.toLowerCase().includes(query) ||
648
+ vault.asset.name.toLowerCase().includes(query));
649
+ return filtered.slice(0, searchOptions.limit || 50);
650
+ }
651
+ /**
652
+ * Get vault details by address
653
+ */
654
+ async getVaultByAddress(address, chainId) {
655
+ const query = `
656
+ query GetVaultByAddress($address: String!, $chainId: Int!) {
657
+ vaultByAddress(address: $address, chainId: $chainId) {
658
+ address
659
+ name
660
+ symbol
661
+ whitelisted
662
+ creationTimestamp
663
+ asset {
664
+ address
665
+ symbol
666
+ name
667
+ decimals
668
+ }
669
+ chain {
670
+ id
671
+ network
672
+ }
673
+ state {
674
+ apy
675
+ netApy
676
+ totalAssets
677
+ totalAssetsUsd
678
+ fee
679
+ rewards {
680
+ asset {
681
+ address
682
+ symbol
683
+ }
684
+ supplyApr
685
+ yearlySupplyTokens
686
+ }
687
+ }
688
+ }
689
+ }
690
+ `;
691
+ const variables = { address, chainId };
692
+ try {
693
+ const data = await this.fetchVaultData(query, variables);
694
+ return data.vaultByAddress ? this.mapVaultData(data.vaultByAddress) : null;
695
+ }
696
+ catch (error) {
697
+ console.error(`Failed to fetch vault ${address}:`, error);
698
+ return null;
699
+ }
700
+ }
701
+ /**
702
+ * Get best vaults for a specific asset
703
+ */
704
+ async getBestVaultsForAsset(assetSymbol, limit = 5) {
705
+ const vaults = await this.getAllVaults({
706
+ sortBy: 'netApy',
707
+ sortOrder: 'desc',
708
+ limit: 100,
709
+ minTvl: 10000, // Minimum $10k TVL
710
+ excludeIdle: true,
711
+ });
712
+ return vaults
713
+ .filter((vault) => vault.asset.symbol.toLowerCase() === assetSymbol.toLowerCase())
714
+ .slice(0, limit);
715
+ }
716
+ /**
717
+ * Map vault data from GraphQL response
718
+ */
719
+ mapVaultData(vault) {
720
+ return {
721
+ address: vault.address,
722
+ name: vault.name,
723
+ symbol: vault.symbol,
724
+ asset: {
725
+ address: vault.asset.address,
726
+ symbol: vault.asset.symbol,
727
+ name: vault.asset.name,
728
+ decimals: vault.asset.decimals,
729
+ },
730
+ chain: {
731
+ id: vault.chain.id,
732
+ network: vault.chain.network,
733
+ },
734
+ metrics: {
735
+ apy: vault.state.apy || 0,
736
+ netApy: vault.state.netApy || 0,
737
+ totalAssets: vault.state.totalAssets || '0',
738
+ totalAssetsUsd: vault.state.totalAssetsUsd || 0,
739
+ fee: vault.state.fee || 0,
740
+ rewards: vault.state.rewards?.map((reward) => ({
741
+ asset: reward.asset.address,
742
+ supplyApr: reward.supplyApr,
743
+ yearlySupplyTokens: reward.yearlySupplyTokens,
744
+ })) || [],
745
+ },
746
+ whitelisted: vault.whitelisted,
747
+ creationTimestamp: vault.creationTimestamp,
748
+ isIdle: vault.state.totalAssetsUsd < 100, // Consider vaults with < $100 TVL as idle
749
+ };
750
+ }
751
+ /**
752
+ * Build GraphQL VaultFilters from filter options
753
+ * Uses proper server-side filtering for better performance
754
+ */
755
+ buildVaultFilters(options) {
756
+ const filters = {};
757
+ // Chain filtering - server-side supported
758
+ if (options.chain !== undefined || options.chainId !== undefined) {
759
+ let targetChainId;
760
+ if (options.chainId !== undefined) {
761
+ targetChainId = options.chainId;
762
+ }
763
+ else if (options.chain !== undefined) {
764
+ targetChainId =
765
+ typeof options.chain === 'string'
766
+ ? exports.CHAIN_IDS[options.chain]
767
+ : options.chain;
768
+ }
769
+ if (targetChainId !== undefined) {
770
+ filters.chainId_in = [targetChainId];
771
+ }
772
+ }
773
+ // Asset filtering - server-side supported
774
+ if (options.assetAddress) {
775
+ filters.assetAddress_in = [options.assetAddress.toLowerCase()];
776
+ }
777
+ if (options.assetSymbol) {
778
+ filters.assetSymbol_in = [options.assetSymbol.toUpperCase()];
779
+ }
780
+ // Whitelisted status filtering - server-side supported
781
+ if (options.whitelistedOnly) {
782
+ filters.whitelisted = true;
783
+ }
784
+ // Net APY filtering - server-side supported
785
+ if (options.minNetApy !== undefined) {
786
+ filters.netApy_gte = options.minNetApy;
787
+ }
788
+ if (options.maxNetApy !== undefined) {
789
+ filters.netApy_lte = options.maxNetApy;
790
+ }
791
+ // TVL filtering - server-side supported
792
+ if (options.minTvl !== undefined) {
793
+ filters.totalAssetsUsd_gte = options.minTvl;
794
+ }
795
+ if (options.maxTvl !== undefined) {
796
+ filters.totalAssetsUsd_lte = options.maxTvl;
797
+ }
798
+ // Total assets filtering - server-side supported
799
+ if (options.minTotalAssets !== undefined) {
800
+ filters.totalAssets_gte = options.minTotalAssets.toString();
801
+ }
802
+ if (options.maxTotalAssets !== undefined) {
803
+ filters.totalAssets_lte = options.maxTotalAssets.toString();
804
+ }
805
+ // Return null if no filters to avoid empty where clause
806
+ return Object.keys(filters).length > 0 ? filters : null;
807
+ }
808
+ /**
809
+ * Apply remaining client-side filters not supported by GraphQL
810
+ * Only handles computed properties like isIdle
811
+ */
812
+ applyRemainingClientFilters(vaults, options) {
813
+ let filtered = vaults;
814
+ // Idle vault filtering (computed client-side)
815
+ if (options.excludeIdle) {
816
+ filtered = filtered.filter((vault) => !vault.isIdle);
817
+ }
818
+ return filtered;
819
+ }
820
+ /**
821
+ * Map sortBy option to GraphQL enum
822
+ */
823
+ mapSortBy(sortBy) {
824
+ switch (sortBy) {
825
+ case 'netApy':
826
+ return 'NetApy';
827
+ case 'totalAssets':
828
+ return 'TotalAssets';
829
+ case 'totalAssetsUsd':
830
+ return 'TotalAssetsUsd';
831
+ case 'creationTimestamp':
832
+ return 'CreationTimestamp';
833
+ default:
834
+ return 'TotalAssetsUsd';
835
+ }
836
+ }
837
+ }
838
+ exports.MorphoVaultClient = MorphoVaultClient;
839
+ /**
840
+ * Create a singleton instance of MorphoVaultClient
841
+ */
842
+ exports.morphoVaultClient = new MorphoVaultClient();
843
+ /**
844
+ * Helper function to get best vaults for a specific asset
845
+ */
846
+ async function getBestVaultsForAsset(assetSymbol, limit = 5) {
847
+ return exports.morphoVaultClient.getBestVaultsForAsset(assetSymbol, limit);
848
+ }
849
+ /**
850
+ * Helper function to get top vaults by APY
851
+ */
852
+ async function getTopVaultsByNetApy(limit = 10, minTvl = 10000) {
853
+ return exports.morphoVaultClient.getTopVaultsByNetApy(limit, minTvl);
854
+ }
855
+ /**
856
+ * Helper function to get top vaults by TVL
857
+ */
858
+ async function getTopVaultsByTvl(limit = 10) {
859
+ return exports.morphoVaultClient.getTopVaultsByTvl(limit);
860
+ }
861
+ /**
862
+ * Helper function to search vaults
863
+ */
864
+ async function searchVaults(query, limit = 20) {
865
+ return exports.morphoVaultClient.searchVaults({ query, limit });
866
+ }
867
+ /**
868
+ * 🚀 **Quick Vault Search with Presets**
869
+ *
870
+ * Get vaults using pre-configured filter presets for common use cases.
871
+ *
872
+ * @param preset - Pre-configured filter preset
873
+ * @param overrides - Additional options to override preset defaults
874
+ * @returns Promise resolving to array of vault information
875
+ *
876
+ * @example
877
+ * ```typescript
878
+ * // Find high-yield vaults
879
+ * const highYieldVaults = await getVaultsByPreset("highYield");
880
+ *
881
+ * // Find high-yield USDC vaults specifically
882
+ * const usdcHighYield = await getVaultsByPreset("highYield", {
883
+ * assetSymbol: "USDC"
884
+ * });
885
+ *
886
+ * // Find stable vaults on Base chain
887
+ * const stableBaseVaults = await getVaultsByPreset("stable", {
888
+ * chainId: 8453
889
+ * });
890
+ * ```
891
+ */
892
+ async function getVaultsByPreset(preset, overrides = {}) {
893
+ const presetOptions = exports.VAULT_FILTER_PRESETS[preset];
894
+ const mergedOptions = { ...presetOptions, ...overrides };
895
+ return getVaults(mergedOptions);
896
+ }
897
+ /**
898
+ * 🔍 **Primary Vault Discovery Function**
899
+ *
900
+ * Get Morpho vaults with comprehensive filtering and sorting options.
901
+ * Uses server-side GraphQL queries for optimal performance.
902
+ *
903
+ * @param options - Vault filtering and sorting options
904
+ * @returns Promise resolving to array of vault information
905
+ *
906
+ * @example
907
+ * ```typescript
908
+ * // Find best USDC vaults across all chains
909
+ * const topVaults = await getVaults({
910
+ * assetSymbol: "USDC",
911
+ * minNetApy: 0.05,
912
+ * minTvl: 1000000,
913
+ * sortBy: "netApy",
914
+ * sortOrder: "desc",
915
+ * limit: 5
916
+ * });
917
+ *
918
+ * // Filter by specific chain
919
+ * const baseVaults = await getVaults({
920
+ * chainId: 8453, // Base
921
+ * excludeIdle: true,
922
+ * sortBy: "totalAssetsUsd"
923
+ * });
924
+ *
925
+ * // Search with multiple criteria
926
+ * const premiumVaults = await getVaults({
927
+ * minNetApy: 10.0,
928
+ * minTvl: 5000000,
929
+ * whitelistedOnly: true,
930
+ * sortBy: "netApy",
931
+ * limit: 3
932
+ * });
933
+ * ```
934
+ */
935
+ async function getVaults(options = {}) {
936
+ return exports.morphoVaultClient.getVaults(options);
937
+ }
938
+ /**
939
+ * Get supported chains with active vaults
940
+ */
941
+ async function getSupportedChainsWithVaults() {
942
+ const supportedChains = getSupportedChainIds();
943
+ const results = [];
944
+ for (const chainId of supportedChains) {
945
+ try {
946
+ const vaults = await exports.morphoVaultClient.getVaults({
947
+ chainId,
948
+ limit: 1,
949
+ excludeIdle: true,
950
+ });
951
+ if (vaults.length > 0) {
952
+ // Get total count - reduced limit to avoid GraphQL errors
953
+ const allVaults = await exports.morphoVaultClient.getVaults({
954
+ chainId,
955
+ limit: 500, // Reduced to avoid GraphQL limit issues
956
+ excludeIdle: true,
957
+ });
958
+ results.push({
959
+ chainId,
960
+ name: getChainName(chainId),
961
+ vaultCount: allVaults.length,
962
+ });
963
+ }
964
+ }
965
+ catch (error) {
966
+ console.warn(`Could not fetch vaults for chain ${chainId}:`, error instanceof Error ? error.message : String(error));
967
+ }
968
+ }
969
+ return results.sort((a, b) => b.vaultCount - a.vaultCount);
970
+ }
971
+ /**
972
+ * Get vault discovery summary for a chain
973
+ */
974
+ async function getVaultDiscoverySummary(chainId) {
975
+ try {
976
+ const [topByTvl, topByNetApy, assetBreakdown] = await Promise.all([
977
+ exports.morphoVaultClient.getVaults({
978
+ chainId,
979
+ sortBy: 'totalAssetsUsd',
980
+ sortOrder: 'desc',
981
+ limit: 5,
982
+ excludeIdle: true,
983
+ }),
984
+ exports.morphoVaultClient.getVaults({
985
+ chainId,
986
+ sortBy: 'netApy',
987
+ sortOrder: 'desc',
988
+ limit: 5,
989
+ excludeIdle: true,
990
+ }),
991
+ exports.morphoVaultClient.getVaults({
992
+ chainId,
993
+ limit: 500, // Reduced to avoid GraphQL limit issues
994
+ excludeIdle: true,
995
+ }),
996
+ ]);
997
+ // Group by asset
998
+ const assetGroups = assetBreakdown.reduce((acc, vault) => {
999
+ const symbol = vault.asset.symbol;
1000
+ if (!acc[symbol]) {
1001
+ acc[symbol] = { count: 0, totalTvl: 0, maxNetApy: 0 };
1002
+ }
1003
+ acc[symbol].count++;
1004
+ acc[symbol].totalTvl += vault.metrics.totalAssetsUsd;
1005
+ acc[symbol].maxNetApy = Math.max(acc[symbol].maxNetApy, vault.metrics.netApy);
1006
+ return acc;
1007
+ }, {});
1008
+ return {
1009
+ chainId,
1010
+ chainName: getChainName(chainId),
1011
+ totalVaults: assetBreakdown.length,
1012
+ totalTvl: assetBreakdown.reduce((sum, v) => sum + v.metrics.totalAssetsUsd, 0),
1013
+ topVaultsByTvl: topByTvl,
1014
+ topVaultsByNetApy: topByNetApy,
1015
+ assetBreakdown: Object.entries(assetGroups)
1016
+ .map(([symbol, data]) => ({ symbol, ...data }))
1017
+ .sort((a, b) => b.totalTvl - a.totalTvl),
1018
+ };
1019
+ }
1020
+ catch (error) {
1021
+ console.error(`Error getting vault summary for chain ${chainId}:`, error);
1022
+ throw error;
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Execute Morpho market operations (supply/withdrawCollateral)
1027
+ */
1028
+ async function executeMorphoMarketOperation({ provider, pkpPublicKey, marketAddress, marketId, functionName, args, chainId, alchemyGasSponsor, alchemyGasSponsorApiKey, alchemyGasSponsorPolicyId, }) {
1029
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoMarketOperation] Starting ${functionName} operation`, { sponsored: !!alchemyGasSponsor, marketId });
1030
+ // Use gas sponsorship if enabled and all required parameters are provided
1031
+ if (alchemyGasSponsor && alchemyGasSponsorApiKey && alchemyGasSponsorPolicyId) {
1032
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoMarketOperation] Using EIP-7702 gas sponsorship`, { marketAddress, functionName, args, policyId: alchemyGasSponsorPolicyId });
1033
+ try {
1034
+ return await vincent_scaffold_sdk_1.laUtils.transaction.handler.sponsoredGasContractCall({
1035
+ pkpPublicKey,
1036
+ abi: exports.MORPHO_MARKET_ABI,
1037
+ contractAddress: marketAddress,
1038
+ functionName,
1039
+ args,
1040
+ chainId,
1041
+ eip7702AlchemyApiKey: alchemyGasSponsorApiKey,
1042
+ eip7702AlchemyPolicyId: alchemyGasSponsorPolicyId,
1043
+ });
1044
+ }
1045
+ catch (error) {
1046
+ console.error(`[@lit-protocol/vincent-ability-morpho/executeMorphoMarketOperation] EIP-7702 operation failed:`, error);
1047
+ throw error;
1048
+ }
1049
+ }
1050
+ else {
1051
+ // Use regular transaction without gas sponsorship
1052
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoMarketOperation] Using regular transaction`);
1053
+ if (!provider) {
1054
+ throw new Error('Provider is required for non-sponsored transactions');
1055
+ }
1056
+ try {
1057
+ return await vincent_scaffold_sdk_1.laUtils.transaction.handler.contractCall({
1058
+ provider,
1059
+ pkpPublicKey,
1060
+ callerAddress: ethers_1.ethers.utils.computeAddress(pkpPublicKey),
1061
+ abi: exports.MORPHO_MARKET_ABI,
1062
+ contractAddress: marketAddress,
1063
+ functionName,
1064
+ args,
1065
+ chainId,
1066
+ });
1067
+ }
1068
+ catch (error) {
1069
+ console.error(`[@lit-protocol/vincent-ability-morpho/executeMorphoMarketOperation] Regular transaction failed:`, error);
1070
+ throw error;
1071
+ }
1072
+ }
1073
+ }
1074
+ /**
1075
+ * Generic function to execute any Morpho Vault operation, with optional gas sponsorship
1076
+ */
1077
+ async function executeMorphoVaultOperation({ provider, pkpPublicKey, vaultAddress, functionName, args, chainId, alchemyGasSponsor, alchemyGasSponsorApiKey, alchemyGasSponsorPolicyId, }) {
1078
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoVaultOperation] Starting ${functionName} operation`, { sponsored: !!alchemyGasSponsor });
1079
+ // Use gas sponsorship if enabled and all required parameters are provided
1080
+ if (alchemyGasSponsor && alchemyGasSponsorApiKey && alchemyGasSponsorPolicyId) {
1081
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoVaultOperation] Using EIP-7702 gas sponsorship`, { vaultAddress, functionName, args, policyId: alchemyGasSponsorPolicyId });
1082
+ try {
1083
+ return await vincent_scaffold_sdk_1.laUtils.transaction.handler.sponsoredGasContractCall({
1084
+ pkpPublicKey,
1085
+ abi: exports.ERC4626_VAULT_ABI,
1086
+ contractAddress: vaultAddress,
1087
+ functionName,
1088
+ args,
1089
+ chainId,
1090
+ eip7702AlchemyApiKey: alchemyGasSponsorApiKey,
1091
+ eip7702AlchemyPolicyId: alchemyGasSponsorPolicyId,
1092
+ });
1093
+ }
1094
+ catch (error) {
1095
+ console.error(`[@lit-protocol/vincent-ability-morpho/executeMorphoVaultOperation] EIP-7702 operation failed:`, error);
1096
+ throw error;
1097
+ }
1098
+ }
1099
+ else {
1100
+ // Use regular transaction without gas sponsorship
1101
+ console.log(`[@lit-protocol/vincent-ability-morpho/executeMorphoVaultOperation] Using regular transaction`);
1102
+ if (!provider) {
1103
+ throw new Error('Provider is required for non-sponsored transactions');
1104
+ }
1105
+ try {
1106
+ return await vincent_scaffold_sdk_1.laUtils.transaction.handler.contractCall({
1107
+ provider,
1108
+ pkpPublicKey,
1109
+ callerAddress: ethers_1.ethers.utils.computeAddress(pkpPublicKey),
1110
+ abi: exports.ERC4626_VAULT_ABI,
1111
+ contractAddress: vaultAddress,
1112
+ functionName,
1113
+ args,
1114
+ chainId,
1115
+ });
1116
+ }
1117
+ catch (error) {
1118
+ console.error(`[@lit-protocol/vincent-ability-morpho/executeMorphoVaultOperation] Regular transaction failed:`, error);
1119
+ throw error;
1120
+ }
1121
+ }
1122
+ }
1123
+ //# sourceMappingURL=index.js.map