@oydual31/more-vaults-sdk 0.3.2 → 0.4.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 (39) hide show
  1. package/dist/ethers/index.cjs +1794 -315
  2. package/dist/ethers/index.cjs.map +1 -1
  3. package/dist/ethers/index.d.cts +1147 -1
  4. package/dist/ethers/index.d.ts +1147 -1
  5. package/dist/ethers/index.js +1752 -317
  6. package/dist/ethers/index.js.map +1 -1
  7. package/dist/react/index.cjs.map +1 -1
  8. package/dist/react/index.d.cts +1 -1
  9. package/dist/react/index.d.ts +1 -1
  10. package/dist/react/index.js.map +1 -1
  11. package/dist/{spokeRoutes-DK7cIW4z.d.cts → spokeRoutes-BIafSbQ3.d.cts} +13 -2
  12. package/dist/{spokeRoutes-DK7cIW4z.d.ts → spokeRoutes-BIafSbQ3.d.ts} +13 -2
  13. package/dist/viem/index.cjs +34 -28
  14. package/dist/viem/index.cjs.map +1 -1
  15. package/dist/viem/index.d.cts +1 -1
  16. package/dist/viem/index.d.ts +1 -1
  17. package/dist/viem/index.js +34 -29
  18. package/dist/viem/index.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/ethers/abis.ts +92 -0
  21. package/src/ethers/chains.ts +191 -0
  22. package/src/ethers/crossChainFlows.ts +208 -0
  23. package/src/ethers/curatorMulticall.ts +195 -0
  24. package/src/ethers/curatorStatus.ts +319 -0
  25. package/src/ethers/curatorSwaps.ts +192 -0
  26. package/src/ethers/distribution.ts +156 -0
  27. package/src/ethers/index.ts +96 -1
  28. package/src/ethers/preflight.ts +225 -1
  29. package/src/ethers/redeemFlows.ts +160 -1
  30. package/src/ethers/spokeRoutes.ts +361 -0
  31. package/src/ethers/topology.ts +240 -0
  32. package/src/ethers/types.ts +95 -0
  33. package/src/ethers/userHelpers.ts +193 -0
  34. package/src/ethers/utils.ts +28 -0
  35. package/src/viem/crossChainFlows.ts +12 -22
  36. package/src/viem/index.ts +1 -0
  37. package/src/viem/preflight.ts +3 -9
  38. package/src/viem/redeemFlows.ts +4 -5
  39. package/src/viem/utils.ts +40 -0
@@ -8,6 +8,9 @@ declare const CHAIN_IDS: {
8
8
  readonly arbitrum: 42161;
9
9
  readonly base: 8453;
10
10
  readonly ethereum: 1;
11
+ readonly optimism: 10;
12
+ readonly sonic: 146;
13
+ readonly bsc: 56;
11
14
  };
12
15
  /**
13
16
  * LayerZero Endpoint IDs (EID) for chains supported by MoreVaults.
@@ -20,11 +23,323 @@ declare const LZ_EIDS: {
20
23
  readonly arbitrum: 30110;
21
24
  readonly base: 30184;
22
25
  readonly ethereum: 30101;
26
+ readonly optimism: 30111;
27
+ readonly sonic: 30332;
28
+ readonly bsc: 30102;
23
29
  };
24
30
  /** LayerZero EID → EVM Chain ID */
25
31
  declare const EID_TO_CHAIN_ID: Record<number, number>;
26
32
  /** EVM Chain ID → LayerZero EID */
27
33
  declare const CHAIN_ID_TO_EID: Record<number, number>;
34
+ /**
35
+ * LayerZero v2 OFT route config per asset symbol.
36
+ *
37
+ * Each entry maps chainId → { oft, token } where:
38
+ * - `oft` = OFT contract to call send() on (pass as `spokeOFT` to depositFromSpoke)
39
+ * - `token` = underlying ERC-20 the user approves before bridging
40
+ * (zero address = native ETH, no approval needed)
41
+ *
42
+ * All routes verified on-chain via quoteSend() or peers(). Issuers vary per asset.
43
+ */
44
+ declare const OFT_ROUTES: {
45
+ /**
46
+ * stgUSDC — USDC bridged via Stargate v2.
47
+ * Underlying on Eth/Arb/Base/Op: native USDC. On Flow: stgUSDC (Stargate's wrapped USDC).
48
+ */
49
+ readonly stgUSDC: {
50
+ readonly 747: {
51
+ readonly oft: "0xAF54BE5B6eEc24d6BFACf1cce4eaF680A8239398";
52
+ readonly token: "0xF1815bd50389c46847f0Bda824eC8da914045D14";
53
+ };
54
+ readonly 1: {
55
+ readonly oft: "0xc026395860Db2d07ee33e05fE50ed7bD583189C7";
56
+ readonly token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
57
+ };
58
+ readonly 42161: {
59
+ readonly oft: "0xe8CDF27AcD73a434D661C84887215F7598e7d0d3";
60
+ readonly token: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
61
+ };
62
+ readonly 8453: {
63
+ readonly oft: "0x27a16dc786820B16E5c9028b75B99F6f604b5d26";
64
+ readonly token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
65
+ };
66
+ readonly 10: {
67
+ readonly oft: "0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0";
68
+ readonly token: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85";
69
+ };
70
+ readonly 146: {
71
+ readonly oft: "0xA272fFe20cFfe769CdFc4b63088DCD2C82a2D8F9";
72
+ readonly token: "0x29219dd400f2Bf60E5a23d13Be72B486D4038894";
73
+ };
74
+ };
75
+ /**
76
+ * USDT — USDT bridged via Stargate v2.
77
+ */
78
+ readonly USDT: {
79
+ readonly 747: {
80
+ readonly oft: "0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6";
81
+ readonly token: "0x674843C06FF83502ddb4D37c2E09C01cdA38cbc8";
82
+ };
83
+ readonly 1: {
84
+ readonly oft: "0x933597a323Eb81cAe705C5bC29985172fd5A3973";
85
+ readonly token: "0xdAC17F958D2ee523a2206206994597C13D831ec7";
86
+ };
87
+ readonly 42161: {
88
+ readonly oft: "0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0";
89
+ readonly token: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
90
+ };
91
+ readonly 10: {
92
+ readonly oft: "0x19cFCE47eD54a88614648DC3f19A5980097007dD";
93
+ readonly token: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58";
94
+ };
95
+ };
96
+ /**
97
+ * USDF — USD Flow OFT. Bridges PYUSD (Ethereum) ↔ USDF (Flow EVM).
98
+ */
99
+ readonly USDF: {
100
+ readonly 747: {
101
+ readonly oft: "0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed";
102
+ readonly token: "0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed";
103
+ };
104
+ readonly 1: {
105
+ readonly oft: "0xfa0e06b54986ad96de87a8c56fea76fbd8d493f8";
106
+ readonly token: "0x6c3ea9036406852006290770BEdFcAbA0e23A0e8";
107
+ };
108
+ };
109
+ /**
110
+ * PYUSD — PayPal USD bridged via OFTAdapter (Paxos / LayerZero).
111
+ */
112
+ readonly PYUSD: {
113
+ readonly 747: {
114
+ readonly oft: "0x26d27d5AF2F6f1c14F40013C8619d97aaf015509";
115
+ readonly token: "0x99aF3EeA856556646C98c8B9b2548Fe815240750";
116
+ };
117
+ readonly 42161: {
118
+ readonly oft: "0x3CD2b89C49D130C08f1d683225b2e5DeB63ff876";
119
+ readonly token: "0x46850aD61C2B7d64d08c9C754F45254596696984";
120
+ };
121
+ };
122
+ /**
123
+ * WFLOW — Wrapped FLOW NativeOFTAdapter (issued by Flow Foundation).
124
+ */
125
+ readonly WFLOW: {
126
+ readonly 747: {
127
+ readonly oft: "0xd296588850bee2770136464ffdddd78c32f2a07c";
128
+ readonly token: "0xd296588850bee2770136464ffdddd78c32f2a07c";
129
+ };
130
+ readonly 1: {
131
+ readonly oft: "0xc1b45896b5fc9422a8f779653808297bb4f546f9";
132
+ readonly token: "0x5c147e74D63B1D31AA3Fd78Eb229B65161983B2b";
133
+ };
134
+ };
135
+ /**
136
+ * WETH — ETH OFT via Stargate v2. underlying = native ETH (no approval needed).
137
+ */
138
+ readonly WETH: {
139
+ readonly 747: {
140
+ readonly oft: "0x45f1A95A4D3f3836523F5c83673c797f4d4d263B";
141
+ readonly token: "0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590";
142
+ };
143
+ readonly 1: {
144
+ readonly oft: "0x77b2043768d28E9C9aB44E1aBfC95944bcE57931";
145
+ readonly token: "0x0000000000000000000000000000000000000000";
146
+ };
147
+ readonly 42161: {
148
+ readonly oft: "0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F";
149
+ readonly token: "0x0000000000000000000000000000000000000000";
150
+ };
151
+ readonly 8453: {
152
+ readonly oft: "0xdc181Bd607330aeeBEF6ea62e03e5e1Fb4B6F7C7";
153
+ readonly token: "0x0000000000000000000000000000000000000000";
154
+ };
155
+ };
156
+ /**
157
+ * sUSDe — Ethena staked USDe (yield-bearing stablecoin).
158
+ */
159
+ readonly sUSDe: {
160
+ readonly 1: {
161
+ readonly oft: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
162
+ readonly token: "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497";
163
+ };
164
+ readonly 42161: {
165
+ readonly oft: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
166
+ readonly token: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
167
+ };
168
+ readonly 8453: {
169
+ readonly oft: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
170
+ readonly token: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
171
+ };
172
+ readonly 10: {
173
+ readonly oft: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
174
+ readonly token: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
175
+ };
176
+ readonly 56: {
177
+ readonly oft: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
178
+ readonly token: "0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2";
179
+ };
180
+ };
181
+ /**
182
+ * USDe — Ethena USD stablecoin.
183
+ */
184
+ readonly USDe: {
185
+ readonly 1: {
186
+ readonly oft: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
187
+ readonly token: "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3";
188
+ };
189
+ readonly 42161: {
190
+ readonly oft: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
191
+ readonly token: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
192
+ };
193
+ readonly 8453: {
194
+ readonly oft: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
195
+ readonly token: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
196
+ };
197
+ readonly 10: {
198
+ readonly oft: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
199
+ readonly token: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
200
+ };
201
+ readonly 56: {
202
+ readonly oft: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
203
+ readonly token: "0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34";
204
+ };
205
+ };
206
+ /**
207
+ * weETH — Ether.Fi liquid restaking token.
208
+ */
209
+ readonly weETH: {
210
+ readonly 1: {
211
+ readonly oft: "0xcd2eb13d6831d4602d80e5db9230a57596cdca63";
212
+ readonly token: "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee";
213
+ };
214
+ readonly 8453: {
215
+ readonly oft: "0x04c0599ae5a44757c0af6f9ec3b93da8976c150a";
216
+ readonly token: "0x04c0599ae5a44757c0af6f9ec3b93da8976c150a";
217
+ };
218
+ readonly 10: {
219
+ readonly oft: "0x5a7facb970d094b6c7ff1df0ea68d99e6e73cbff";
220
+ readonly token: "0x5a7facb970d094b6c7ff1df0ea68d99e6e73cbff";
221
+ };
222
+ readonly 56: {
223
+ readonly oft: "0x04c0599ae5a44757c0af6f9ec3b93da8976c150a";
224
+ readonly token: "0x04c0599ae5a44757c0af6f9ec3b93da8976c150a";
225
+ };
226
+ readonly 146: {
227
+ readonly oft: "0xa3d68b74bf0528fdd07263c60d6488749044914b";
228
+ readonly token: "0xa3d68b74bf0528fdd07263c60d6488749044914b";
229
+ };
230
+ };
231
+ /**
232
+ * rsETH — Kelp DAO liquid restaking token.
233
+ */
234
+ readonly rsETH: {
235
+ readonly 1: {
236
+ readonly oft: "0x85d456b2dff1fd8245387c0bfb64dfb700e98ef3";
237
+ readonly token: "0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7";
238
+ };
239
+ readonly 42161: {
240
+ readonly oft: "0x4186bfc76e2e237523cbc30fd220fe055156b41f";
241
+ readonly token: "0x4186bfc76e2e237523cbc30fd220fe055156b41f";
242
+ };
243
+ readonly 8453: {
244
+ readonly oft: "0x1bc71130a0e39942a7658878169764bbd8a45993";
245
+ readonly token: "0x1bc71130a0e39942a7658878169764bbd8a45993";
246
+ };
247
+ readonly 10: {
248
+ readonly oft: "0x4186bfc76e2e237523cbc30fd220fe055156b41f";
249
+ readonly token: "0x4186bfc76e2e237523cbc30fd220fe055156b41f";
250
+ };
251
+ readonly 146: {
252
+ readonly oft: "0xd75787ba9aba324420d522bda84c08c87e5099b1";
253
+ readonly token: "0xd75787ba9aba324420d522bda84c08c87e5099b1";
254
+ };
255
+ };
256
+ /**
257
+ * rswETH — Swell Network liquid restaking token.
258
+ */
259
+ readonly rswETH: {
260
+ readonly 1: {
261
+ readonly oft: "0x1486d39646cdee84619bd05997319545a8575079";
262
+ readonly token: "0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0";
263
+ };
264
+ readonly 42161: {
265
+ readonly oft: "0xb1fe27b32ffb5ce54e272c096547f1e86c19e72f";
266
+ readonly token: "0xb1fe27b32ffb5ce54e272c096547f1e86c19e72f";
267
+ };
268
+ readonly 8453: {
269
+ readonly oft: "0x850cdf416668210ed0c36bfff5d21921c7ada3b8";
270
+ readonly token: "0x850cdf416668210ed0c36bfff5d21921c7ada3b8";
271
+ };
272
+ };
273
+ /**
274
+ * USR — Resolv Labs USD stablecoin.
275
+ */
276
+ readonly USR: {
277
+ readonly 1: {
278
+ readonly oft: "0xd2ee2776f34ef4e7325745b06e6d464b08d4be0e";
279
+ readonly token: "0x66a1E37c9b0eAddca17d3662D6c05F4DECf3e110";
280
+ };
281
+ readonly 42161: {
282
+ readonly oft: "0x2492d0006411af6c8bbb1c8afc1b0197350a79e9";
283
+ readonly token: "0x2492d0006411af6c8bbb1c8afc1b0197350a79e9";
284
+ };
285
+ readonly 8453: {
286
+ readonly oft: "0x35e5db674d8e93a03d814fa0ada70731efe8a4b9";
287
+ readonly token: "0x35e5db674d8e93a03d814fa0ada70731efe8a4b9";
288
+ };
289
+ readonly 56: {
290
+ readonly oft: "0x2492d0006411af6c8bbb1c8afc1b0197350a79e9";
291
+ readonly token: "0x2492d0006411af6c8bbb1c8afc1b0197350a79e9";
292
+ };
293
+ };
294
+ /**
295
+ * wstUSR — Resolv Labs wrapped staked USR (yield-bearing).
296
+ */
297
+ readonly wstUSR: {
298
+ readonly 1: {
299
+ readonly oft: "0xab17c1fe647c37ceb9b96d1c27dd189bf8451978";
300
+ readonly token: "0x1202F5C7b4B9E47a1A484E8B270be34dbbC75055";
301
+ };
302
+ readonly 42161: {
303
+ readonly oft: "0x66cfbd79257dc5217903a36293120282548e2254";
304
+ readonly token: "0x66cfbd79257dc5217903a36293120282548e2254";
305
+ };
306
+ readonly 8453: {
307
+ readonly oft: "0xb67675158b412d53fe6b68946483ba920b135ba1";
308
+ readonly token: "0xb67675158b412d53fe6b68946483ba920b135ba1";
309
+ };
310
+ readonly 56: {
311
+ readonly oft: "0x4254813524695def4163a169e901f3d7a1a55429";
312
+ readonly token: "0x4254813524695def4163a169e901f3d7a1a55429";
313
+ };
314
+ };
315
+ /**
316
+ * USDtb — Ethena treasury-backed stablecoin.
317
+ */
318
+ readonly USDtb: {
319
+ readonly 1: {
320
+ readonly oft: "0xc708b6887db46005da033501f8aebee72d191a5d";
321
+ readonly token: "0xC139190F447e929f090Edeb554D95AbB8b18aC1C";
322
+ };
323
+ readonly 42161: {
324
+ readonly oft: "0xc708b6887db46005da033501f8aebee72d191a5d";
325
+ readonly token: "0xc708b6887db46005da033501f8aebee72d191a5d";
326
+ };
327
+ readonly 8453: {
328
+ readonly oft: "0xc708b6887db46005da033501f8aebee72d191a5d";
329
+ readonly token: "0xc708b6887db46005da033501f8aebee72d191a5d";
330
+ };
331
+ };
332
+ };
333
+ /**
334
+ * Uniswap V3 SwapRouter addresses per chain.
335
+ * Used by curator swap helpers to build calldata for on-chain swaps.
336
+ *
337
+ * Note on struct differences:
338
+ * - SwapRouter (Eth/Arb/Op, 0xE592...): exactInputSingle struct includes `deadline`
339
+ * - SwapRouter02 (Base, 0x2626...): exactInputSingle struct does NOT include `deadline`
340
+ * - FlowSwap V3 (Flow EVM, 0xeEDC...): derived from original UniV3, includes `deadline`
341
+ */
342
+ declare const UNISWAP_V3_ROUTERS: Record<number, string>;
28
343
  /**
29
344
  * Recommended timeouts for cross-chain operations (milliseconds).
30
345
  * UIs should show a progress indicator and NOT timeout before these values.
@@ -107,6 +422,104 @@ interface CrossChainRequestInfo {
107
422
  finalizationResult: bigint;
108
423
  amountLimit: bigint;
109
424
  }
425
+ interface SwapParams {
426
+ targetContract: string;
427
+ tokenIn: string;
428
+ tokenOut: string;
429
+ maxAmountIn: bigint;
430
+ minAmountOut: bigint;
431
+ swapCallData: string;
432
+ }
433
+ interface BatchSwapParams {
434
+ swaps: SwapParams[];
435
+ }
436
+ interface BridgeParams {
437
+ oftToken: string;
438
+ dstEid: number;
439
+ amount: bigint;
440
+ dstVault: string;
441
+ refundAddress: string;
442
+ }
443
+ interface PendingAction {
444
+ nonce: bigint;
445
+ actionsData: string[];
446
+ pendingUntil: bigint;
447
+ isExecutable: boolean;
448
+ }
449
+ interface SubmitActionsResult {
450
+ receipt: ContractTransactionReceipt;
451
+ nonce: bigint;
452
+ }
453
+ type CuratorAction = {
454
+ type: 'swap';
455
+ params: SwapParams;
456
+ } | {
457
+ type: 'batchSwap';
458
+ params: BatchSwapParams;
459
+ } | {
460
+ type: 'erc4626Deposit';
461
+ vault: string;
462
+ assets: bigint;
463
+ } | {
464
+ type: 'erc4626Redeem';
465
+ vault: string;
466
+ shares: bigint;
467
+ } | {
468
+ type: 'erc7540RequestDeposit';
469
+ vault: string;
470
+ assets: bigint;
471
+ } | {
472
+ type: 'erc7540Deposit';
473
+ vault: string;
474
+ assets: bigint;
475
+ } | {
476
+ type: 'erc7540RequestRedeem';
477
+ vault: string;
478
+ shares: bigint;
479
+ } | {
480
+ type: 'erc7540Redeem';
481
+ vault: string;
482
+ shares: bigint;
483
+ };
484
+ interface CuratorVaultStatus {
485
+ curator: string;
486
+ timeLockPeriod: bigint;
487
+ maxSlippagePercent: bigint;
488
+ currentNonce: bigint;
489
+ availableAssets: string[];
490
+ lzAdapter: string;
491
+ paused: boolean;
492
+ }
493
+ interface AssetInfo {
494
+ address: string;
495
+ symbol: string;
496
+ name: string;
497
+ decimals: number;
498
+ }
499
+ interface VaultAnalysis {
500
+ /** All tokens the vault can hold/swap (curator-managed) */
501
+ availableAssets: AssetInfo[];
502
+ /** Tokens users can deposit */
503
+ depositableAssets: AssetInfo[];
504
+ /** Whether deposit whitelist is enabled (restricts who can deposit) */
505
+ depositWhitelistEnabled: boolean;
506
+ /** Registry address for global protocol whitelist checks */
507
+ registryAddress: string | null;
508
+ }
509
+ interface AssetBalance extends AssetInfo {
510
+ /** Raw balance held by the vault */
511
+ balance: bigint;
512
+ }
513
+ interface VaultAssetBreakdown {
514
+ /** Per-asset balances held by the vault on the hub chain */
515
+ assets: AssetBalance[];
516
+ /** totalAssets() as reported by the vault (all positions converted to underlying) */
517
+ totalAssets: bigint;
518
+ /** totalSupply() of vault shares */
519
+ totalSupply: bigint;
520
+ /** Vault underlying token decimals */
521
+ underlyingDecimals: number;
522
+ }
110
523
 
111
524
  /**
112
525
  * Human-readable ABI fragments for MoreVaults diamond facets.
@@ -119,6 +532,42 @@ declare const METADATA_ABI: readonly ["function name() view returns (string)", "
119
532
  declare const ERC20_ABI: readonly ["function approve(address spender, uint256 amount) returns (bool)", "function allowance(address owner, address spender) view returns (uint256)", "function balanceOf(address account) view returns (uint256)", "function transfer(address to, uint256 amount) returns (bool)"];
120
533
  declare const OFT_ABI: readonly ["function send(tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd) sendParam, tuple(uint256 nativeFee, uint256 lzTokenFee) fee, address refundAddress) payable returns (tuple(bytes32 guid, uint64 nonce, uint256 amountSentLD, uint256 amountReceivedLD) receipt, tuple(uint256 nativeFee, uint256 lzTokenFee) fee)", "function quoteSend(tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd) sendParam, bool payInLzToken) view returns (tuple(uint256 nativeFee, uint256 lzTokenFee))"];
121
534
  declare const LZ_ENDPOINT_ABI: readonly ["function composeQueue(address from, address to, bytes32 guid, uint16 index) view returns (bytes32 messageHash)", "function lzCompose(address _from, address _to, bytes32 _guid, uint16 _index, bytes _message, bytes _extraData) payable"];
535
+ /**
536
+ * MulticallFacet ABI — curator action submission and execution with timelock.
537
+ */
538
+ declare const MULTICALL_ABI: readonly ["function submitActions(bytes[] actionsData) returns (uint256 nonce)", "function executeActions(uint256 actionsNonce)", "function getPendingActions(uint256 actionsNonce) view returns (bytes[] actionsData, uint256 pendingUntil)", "function getCurrentNonce() view returns (uint256)", "function vetoActions(uint256[] actionsNonces)"];
539
+ /**
540
+ * GenericDexFacet ABI — single and batch token swaps through any DEX aggregator.
541
+ */
542
+ declare const DEX_ABI: readonly ["function executeSwap(tuple(address targetContract, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 minAmountOut, bytes swapCallData) params) returns (uint256 amountOut)", "function executeBatchSwap(tuple(tuple(address targetContract, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 minAmountOut, bytes swapCallData)[] swaps) params) returns (uint256[] amountsOut)"];
543
+ /**
544
+ * BridgeFacet ABI — curator bridging and cross-chain request initiation.
545
+ */
546
+ declare const BRIDGE_FACET_ABI: readonly ["function executeBridging(address adapter, address token, uint256 amount, bytes bridgeSpecificParams) payable", "function initVaultActionRequest(uint8 actionType, bytes actionCallData, uint256 amountLimit, bytes extraOptions) payable returns (bytes32 guid)", "function executeRequest(bytes32 guid)"];
547
+ /**
548
+ * ERC7540Facet ABI — async deposit and redeem operations on ERC7540 vaults.
549
+ */
550
+ declare const ERC7540_FACET_ABI: readonly ["function erc7540RequestDeposit(address vault, uint256 assets) returns (uint256 requestId)", "function erc7540RequestRedeem(address vault, uint256 shares) returns (uint256 requestId)", "function erc7540Deposit(address vault, uint256 assets) returns (uint256 shares)", "function erc7540Redeem(address vault, uint256 shares) returns (uint256 assets)"];
551
+ /**
552
+ * ERC4626Facet ABI — synchronous deposit and redeem into whitelisted ERC-4626 vaults.
553
+ */
554
+ declare const ERC4626_FACET_ABI: readonly ["function erc4626Deposit(address vault, uint256 assets) returns (uint256 shares)", "function erc4626Redeem(address vault, uint256 shares) returns (uint256 assets)"];
555
+ /**
556
+ * ConfigurationFacet ABI — extended with curator-relevant read functions.
557
+ */
558
+ declare const CURATOR_CONFIG_ABI: readonly ["function curator() view returns (address)", "function timeLockPeriod() view returns (uint256)", "function getAvailableAssets() view returns (address[])", "function getMaxSlippagePercent() view returns (uint256)", "function getCrossChainAccountingManager() view returns (address)", "function paused() view returns (bool)"];
559
+ /**
560
+ * LzAdapter ABI — fee quoting for bridge and LZ Read operations.
561
+ */
562
+ declare const LZ_ADAPTER_ABI: readonly ["function quoteBridgeFee(bytes bridgeSpecificParams) view returns (uint256 nativeFee)", "function quoteReadFee(address[] vaults, uint32[] eids, bytes _extraOptions) view returns (tuple(uint256 nativeFee, uint256 lzTokenFee) fee)"];
563
+ /**
564
+ * Vault analysis ABIs — per-vault whitelist and registry reads.
565
+ */
566
+ declare const VAULT_ANALYSIS_ABI: readonly ["function getAvailableAssets() view returns (address[])", "function getDepositableAssets() view returns (address[])", "function isAssetAvailable(address asset) view returns (bool)", "function isAssetDepositable(address asset) view returns (bool)", "function isDepositWhitelistEnabled() view returns (bool)", "function getAvailableToDeposit(address depositor) view returns (uint256)", "function moreVaultsRegistry() view returns (address)"];
567
+ /**
568
+ * MoreVaultsRegistry ABI — global protocol and bridge whitelist checks.
569
+ */
570
+ declare const REGISTRY_ABI: readonly ["function isWhitelisted(address protocol) view returns (bool)", "function isBridgeAllowed(address bridge) view returns (bool)", "function getAllowedFacets() view returns (address[])"];
122
571
 
123
572
  /**
124
573
  * Typed error classes for the MoreVaults SDK.
@@ -331,6 +780,50 @@ declare function quoteComposeFee(provider: Provider, vault: string, spokeEid?: n
331
780
  declare function executeCompose(signer: Signer, from: string, to: string, guid: string, message: string, fee: bigint, index?: number): Promise<{
332
781
  receipt: ContractTransactionReceipt;
333
782
  }>;
783
+ /**
784
+ * Data needed to execute a pending LZ compose on the hub chain.
785
+ * Returned by `depositFromSpoke` when the OFT is a Stargate V2 pool.
786
+ * The SDK user must call `executeCompose()` with this data as TX2 on the hub.
787
+ */
788
+ interface ComposeData {
789
+ /** LZ Endpoint address on the hub chain */
790
+ endpoint: string;
791
+ /** The OFT/pool address that sent the compose (Stargate pool on hub) — resolved by waitForCompose */
792
+ from: string;
793
+ /** MoreVaultsComposer address on the hub */
794
+ to: string;
795
+ /** LayerZero GUID from the original OFT.send() */
796
+ guid: string;
797
+ /** Compose index (default 0) */
798
+ index: number;
799
+ /** Full compose message bytes — resolved by waitForCompose from ComposeSent event */
800
+ message: string;
801
+ /** Whether this is a Stargate OFT (2-TX flow) */
802
+ isStargate: boolean;
803
+ /** Hub chain ID */
804
+ hubChainId: number;
805
+ /** Block number on hub chain right before depositFromSpoke TX — used to bound event scan */
806
+ hubBlockStart: bigint;
807
+ }
808
+ /**
809
+ * Wait for a pending compose to appear in the LZ Endpoint's composeQueue on the hub chain.
810
+ *
811
+ * After `depositFromSpoke` sends tokens via Stargate, the LZ network delivers the message
812
+ * to the hub chain. The endpoint stores the compose hash in `composeQueue` and emits
813
+ * a `ComposeSent` event with the full message bytes.
814
+ *
815
+ * Strategy: scan ComposeSent events on the LZ Endpoint starting from `hubBlockStart`
816
+ * (captured by `depositFromSpoke` right before TX1). We scan forward in 500-block chunks,
817
+ * matching by composer address and receiver in the message body.
818
+ *
819
+ * @param hubProvider Read-only provider on the HUB chain
820
+ * @param composeData Partial compose data (includes hubBlockStart, to, guid)
821
+ * @param receiver Receiver address to match in the compose message
822
+ * @param pollIntervalMs Polling interval (default 20s)
823
+ * @param timeoutMs Timeout (default 30 min)
824
+ * @returns Complete ComposeData ready for executeCompose
825
+ */
826
+ declare function waitForCompose(hubProvider: Provider, composeData: ComposeData, receiver: string, pollIntervalMs?: number, timeoutMs?: number): Promise<ComposeData>;
334
827
 
335
828
  /**
336
829
  * Redeem `shares` for underlying assets.
@@ -464,6 +957,52 @@ declare function smartRedeem(signer: Signer, addresses: VaultAddresses, shares:
464
957
  declare function bridgeAssetsToSpoke(signer: Signer, assetOFT: string, spokeChainEid: number, amount: bigint, receiver: string, lzFee: bigint, isStargate?: boolean): Promise<{
465
958
  receipt: ContractTransactionReceipt;
466
959
  }>;
960
+ interface SpokeRedeemRoute {
961
+ /** Hub chain ID */
962
+ hubChainId: number;
963
+ /** Spoke chain ID */
964
+ spokeChainId: number;
965
+ /** LZ EID for the hub */
966
+ hubEid: number;
967
+ /** LZ EID for the spoke */
968
+ spokeEid: number;
969
+ /** Vault underlying asset address on hub */
970
+ hubAsset: string;
971
+ /** SHARE_OFT on spoke chain */
972
+ spokeShareOft: string;
973
+ /** Asset OFT on hub for bridging back */
974
+ hubAssetOft: string;
975
+ /** Underlying asset address on spoke chain */
976
+ spokeAsset: string;
977
+ /** Whether the asset OFT is a Stargate pool */
978
+ isStargate: boolean;
979
+ /** OFT route symbol (e.g. 'stgUSDC') */
980
+ symbol: string;
981
+ }
982
+ /**
983
+ * Quote the LZ fee for bridging shares from spoke to hub via SHARE_OFT.
984
+ *
985
+ * IMPORTANT: `amountLD` must be in SHARE_OFT native decimals (e.g. 18),
986
+ * NOT vault decimals (e.g. 8). Use the raw `SHARE_OFT.balanceOf(user)` value.
987
+ *
988
+ * @param spokeProvider Read-only provider on the SPOKE chain
989
+ * @param shareOFT SHARE_OFT address on the spoke chain
990
+ * @param hubChainEid LayerZero Endpoint ID for the hub chain
991
+ * @param amountLD Shares in SHARE_OFT native decimals (raw balanceOf)
992
+ * @param receiver Receiver address on the hub chain
993
+ * @returns LZ native fee in wei
994
+ */
995
+ declare function quoteShareBridgeFee(spokeProvider: Provider, shareOFT: string, hubChainEid: number, amountLD: bigint, receiver: string): Promise<bigint>;
996
+ /**
997
+ * Resolve all addresses needed for a full spoke→hub→spoke redeem flow.
998
+ *
999
+ * @param hubProvider Read-only provider on the HUB chain
1000
+ * @param vault Vault address
1001
+ * @param hubChainId Hub chain ID
1002
+ * @param spokeChainId Spoke chain ID where user has shares
1003
+ * @returns All addresses needed for bridgeSharesToHub + redeemShares + bridgeAssetsToSpoke
1004
+ */
1005
+ declare function resolveRedeemAddresses(hubProvider: Provider, vault: string, hubChainId: number, spokeChainId: number): Promise<SpokeRedeemRoute>;
467
1006
 
468
1007
  /**
469
1008
  * Utility helpers for the MoreVaults ethers.js v6 SDK.
@@ -586,6 +1125,17 @@ declare function getAsyncRequestStatus(provider: Provider, vault: string, guid:
586
1125
  * @returns Full vault status snapshot
587
1126
  */
588
1127
  declare function getVaultStatus(provider: Provider, vault: string): Promise<VaultStatus>;
1128
+ /**
1129
+ * Detect whether an OFT address is a Stargate V2 pool by calling `stargateType()`.
1130
+ *
1131
+ * Stargate pools implement this function (returns 0=Pool, 1=OFT).
1132
+ * Standard OFTs revert because they don't have it.
1133
+ *
1134
+ * @param provider Read-only provider on the OFT's chain
1135
+ * @param oft OFT contract address
1136
+ * @returns true if the contract is a Stargate V2 pool/OFT
1137
+ */
1138
+ declare function detectStargateOft(provider: Provider, oft: string): Promise<boolean>;
589
1139
 
590
1140
  /**
591
1141
  * Pre-flight validation helpers for MoreVaults ethers.js v6 SDK flows.
@@ -640,6 +1190,63 @@ declare function preflightRedeemLiquidity(provider: Provider, vault: string, sha
640
1190
  * @param vault Vault address (diamond proxy)
641
1191
  */
642
1192
  declare function preflightSync(provider: Provider, vault: string): Promise<void>;
1193
+ /**
1194
+ * Pre-flight checks for spoke-to-hub deposits (D6 / D7 via OFT Compose).
1195
+ *
1196
+ * Validates that:
1197
+ * 1. User has enough tokens on the spoke chain to deposit.
1198
+ * 2. User has enough native gas on the spoke chain for TX1 (OFT.send).
1199
+ * 3. For Stargate OFTs (2-TX flow): user has enough ETH on the hub chain for TX2.
1200
+ *
1201
+ * @param spokeProvider Read-only provider on the SPOKE chain
1202
+ * @param vault Vault address
1203
+ * @param spokeOFT OFT contract address on the spoke chain
1204
+ * @param hubEid LZ EID for the hub chain
1205
+ * @param spokeEid LZ EID for the spoke chain
1206
+ * @param amount Amount of tokens to deposit
1207
+ * @param userAddress User's wallet address
1208
+ * @param lzFee LZ fee for TX1 (from quoteDepositFromSpokeFee)
1209
+ * @returns Object with validated balances for UI display
1210
+ */
1211
+ declare function preflightSpokeDeposit(spokeProvider: Provider, vault: string, spokeOFT: string, hubEid: number, spokeEid: number, amount: bigint, userAddress: string, lzFee: bigint): Promise<{
1212
+ spokeTokenBalance: bigint;
1213
+ spokeNativeBalance: bigint;
1214
+ hubNativeBalance: bigint;
1215
+ estimatedComposeFee: bigint;
1216
+ isStargate: boolean;
1217
+ }>;
1218
+ /**
1219
+ * Pre-flight checks for spoke→hub→spoke redeem (R6 + R1 + R7).
1220
+ *
1221
+ * Validates that:
1222
+ * 1. User has shares on the spoke chain.
1223
+ * 2. User has enough native gas on the spoke for TX1.
1224
+ * 3. User has enough native gas on the hub for TX2 (redeem) + TX3 (asset bridge).
1225
+ *
1226
+ * @param route SpokeRedeemRoute from resolveRedeemAddresses
1227
+ * @param shares Shares the user intends to redeem
1228
+ * @param userAddress User's wallet address
1229
+ * @param shareBridgeFee LZ fee for share bridge (TX1)
1230
+ * @returns Validated balances for UI display
1231
+ */
1232
+ declare function preflightSpokeRedeem(route: {
1233
+ hubChainId: number;
1234
+ spokeChainId: number;
1235
+ hubEid: number;
1236
+ spokeEid: number;
1237
+ hubAsset: string;
1238
+ spokeShareOft: string;
1239
+ hubAssetOft: string;
1240
+ spokeAsset: string;
1241
+ isStargate: boolean;
1242
+ }, shares: bigint, userAddress: string, shareBridgeFee: bigint): Promise<{
1243
+ sharesOnSpoke: bigint;
1244
+ spokeNativeBalance: bigint;
1245
+ hubNativeBalance: bigint;
1246
+ estimatedAssetBridgeFee: bigint;
1247
+ estimatedAssetsOut: bigint;
1248
+ hubLiquidBalance: bigint;
1249
+ }>;
643
1250
 
644
1251
  /**
645
1252
  * User-facing helper functions for the MoreVaults ethers.js v6 SDK.
@@ -781,6 +1388,545 @@ type VaultSummary = VaultStatus & VaultMetadata;
781
1388
  * @returns Merged VaultStatus and VaultMetadata
782
1389
  */
783
1390
  declare function getVaultSummary(provider: Provider, vault: string): Promise<VaultSummary>;
1391
+ interface MultiChainUserPosition {
1392
+ /** Shares held directly on the hub vault (vault.balanceOf) */
1393
+ hubShares: bigint;
1394
+ /** Per-spoke SHARE_OFT balances normalized to vault decimals: { [chainId]: bigint } */
1395
+ spokeShares: Record<number, bigint>;
1396
+ /** Per-spoke SHARE_OFT raw balances in OFT native decimals: { [chainId]: bigint }
1397
+ * Use these for bridgeSharesToHub() and quoteShareBridgeFee() */
1398
+ rawSpokeShares: Record<number, bigint>;
1399
+ /** hubShares + sum of all spokeShares (in vault decimals) */
1400
+ totalShares: bigint;
1401
+ /** convertToAssets(totalShares) on the hub */
1402
+ estimatedAssets: bigint;
1403
+ /** Share price: convertToAssets(10^decimals) */
1404
+ sharePrice: bigint;
1405
+ /** Vault decimals */
1406
+ decimals: number;
1407
+ /** Pending async withdrawal request on hub, or null */
1408
+ pendingWithdrawal: {
1409
+ shares: bigint;
1410
+ timelockEndsAt: bigint;
1411
+ canRedeemNow: boolean;
1412
+ } | null;
1413
+ }
1414
+ /**
1415
+ * Read the user's position across all chains of an omni vault.
1416
+ *
1417
+ * Discovers topology automatically, reads hub shares + pending withdrawal,
1418
+ * then reads SHARE_OFT balances on each spoke chain in parallel.
1419
+ *
1420
+ * For local (single-chain) vaults, spokeShares will be empty and this
1421
+ * behaves identically to getUserPosition.
1422
+ *
1423
+ * @param vault Vault address (same on all chains via CREATE3)
1424
+ * @param user User wallet address
1425
+ * @returns Aggregated position across all chains
1426
+ */
1427
+ declare function getUserPositionMultiChain(vault: string, user: string): Promise<MultiChainUserPosition>;
1428
+
1429
+ /**
1430
+ * Curator / vault-manager read helpers for the MoreVaults ethers.js v6 SDK.
1431
+ *
1432
+ * All functions are read-only (no wallet needed) and use Multicall3 for
1433
+ * batched RPC efficiency.
1434
+ */
1435
+
1436
+ /**
1437
+ * Read a comprehensive status snapshot for the curator dashboard.
1438
+ *
1439
+ * Fetches in one multicall batch:
1440
+ * curator, timeLockPeriod, getMaxSlippagePercent, getCurrentNonce,
1441
+ * getAvailableAssets, getCrossChainAccountingManager, paused
1442
+ *
1443
+ * @param provider Read-only provider (must be on the vault's chain)
1444
+ * @param vault Vault address (diamond proxy)
1445
+ * @returns CuratorVaultStatus snapshot
1446
+ */
1447
+ declare function getCuratorVaultStatus(provider: Provider, vault: string): Promise<CuratorVaultStatus>;
1448
+ /**
1449
+ * Fetch pending actions for a specific nonce and resolve whether they are
1450
+ * executable (i.e. the timelock has expired).
1451
+ *
1452
+ * @param provider Read-only provider (must be on the vault's chain)
1453
+ * @param vault Vault address (diamond proxy)
1454
+ * @param nonce Action nonce to query
1455
+ * @returns PendingAction with isExecutable flag set
1456
+ */
1457
+ declare function getPendingActions(provider: Provider, vault: string, nonce: bigint): Promise<PendingAction>;
1458
+ /**
1459
+ * Check whether a given address is the curator of the vault.
1460
+ *
1461
+ * @param provider Read-only provider (must be on the vault's chain)
1462
+ * @param vault Vault address (diamond proxy)
1463
+ * @param address Address to check
1464
+ * @returns true if address is the current curator
1465
+ */
1466
+ declare function isCurator(provider: Provider, vault: string, address: string): Promise<boolean>;
1467
+ /**
1468
+ * Full vault analysis — available assets with metadata, depositable assets, whitelist config.
1469
+ * Useful for curator dashboards to understand what the vault can do.
1470
+ *
1471
+ * @param provider Read-only provider (must be on the vault's chain)
1472
+ * @param vault Vault address (diamond proxy)
1473
+ * @returns VaultAnalysis snapshot
1474
+ */
1475
+ declare function getVaultAnalysis(provider: Provider, vault: string): Promise<VaultAnalysis>;
1476
+ /**
1477
+ * Check if specific protocol addresses are whitelisted in the global registry.
1478
+ * Useful for curators to verify DEX routers before building swap calldata.
1479
+ *
1480
+ * @param provider Read-only provider (must be on the vault's chain)
1481
+ * @param vault Vault address (diamond proxy)
1482
+ * @param protocols Protocol addresses to check
1483
+ * @returns Record mapping address → whitelisted boolean
1484
+ */
1485
+ declare function checkProtocolWhitelist(provider: Provider, vault: string, protocols: string[]): Promise<Record<string, boolean>>;
1486
+ /**
1487
+ * Get the vault's per-asset balance breakdown on the hub chain.
1488
+ *
1489
+ * Returns the balance of every available asset held by the vault, plus
1490
+ * totalAssets and totalSupply for context. Useful for portfolio views
1491
+ * that need to show individual holdings rather than a single USD-denominated total.
1492
+ *
1493
+ * @param provider Read-only provider (must be on the vault's hub chain)
1494
+ * @param vault Vault address (diamond proxy)
1495
+ * @returns VaultAssetBreakdown with per-asset balances
1496
+ */
1497
+ declare function getVaultAssetBreakdown(provider: Provider, vault: string): Promise<VaultAssetBreakdown>;
1498
+
1499
+ /**
1500
+ * Curator MulticallFacet write operations for the MoreVaults ethers.js v6 SDK.
1501
+ *
1502
+ * Provides typed helpers to submit, execute, and veto curator action batches
1503
+ * on any MoreVaults diamond that has the MulticallFacet installed.
1504
+ *
1505
+ * @module curatorMulticall
1506
+ */
1507
+
1508
+ /**
1509
+ * Encode a single typed CuratorAction into raw calldata bytes suitable for
1510
+ * passing into `submitActions(bytes[] actionsData)`.
1511
+ *
1512
+ * The encoded bytes are the full ABI-encoded function call (4-byte selector +
1513
+ * arguments) targeting the vault diamond itself — the MulticallFacet will
1514
+ * call `address(this).call(actionsData[i])` for each entry.
1515
+ *
1516
+ * @param action A discriminated-union CuratorAction describing what to do
1517
+ * @returns ABI-encoded calldata hex string
1518
+ */
1519
+ declare function encodeCuratorAction(action: CuratorAction): string;
1520
+ /**
1521
+ * Encode an array of CuratorActions into a calldata array ready for
1522
+ * `submitActions`.
1523
+ *
1524
+ * @param actions Array of typed CuratorAction objects
1525
+ * @returns Array of ABI-encoded calldata hex strings
1526
+ */
1527
+ declare function buildCuratorBatch(actions: CuratorAction[]): string[];
1528
+ /**
1529
+ * Submit a batch of curator actions to the vault's MulticallFacet.
1530
+ *
1531
+ * When `timeLockPeriod == 0` the contract immediately executes the actions
1532
+ * inside `submitActions` itself. When a timelock is configured the actions
1533
+ * are queued and must be executed later with `executeActions`.
1534
+ *
1535
+ * After the write succeeds, reads `getCurrentNonce` to determine which nonce
1536
+ * was assigned (nonce - 1 after the submit increments it).
1537
+ *
1538
+ * @param signer Signer with curator account attached
1539
+ * @param vault Vault address (diamond proxy)
1540
+ * @param actions Array of raw calldata bytes — use `buildCuratorBatch` to build
1541
+ * @returns Receipt and the nonce assigned to this batch
1542
+ */
1543
+ declare function submitActions(signer: Signer, vault: string, actions: string[]): Promise<SubmitActionsResult>;
1544
+ /**
1545
+ * Execute pending actions after their timelock period has expired.
1546
+ *
1547
+ * Can only be called when `block.timestamp >= pendingUntil`. The contract
1548
+ * reverts with `ActionsStillPending` if the timelock has not expired.
1549
+ *
1550
+ * @param signer Signer with curator account attached
1551
+ * @param vault Vault address (diamond proxy)
1552
+ * @param nonce The action batch nonce to execute
1553
+ * @returns Transaction receipt
1554
+ */
1555
+ declare function executeActions(signer: Signer, vault: string, nonce: bigint): Promise<ContractTransactionReceipt>;
1556
+ /**
1557
+ * Guardian-only: cancel (veto) one or more pending action batches.
1558
+ *
1559
+ * Deletes the pending actions from storage, preventing them from ever being
1560
+ * executed. Only the vault guardian can call this.
1561
+ *
1562
+ * @param signer Signer with guardian account attached
1563
+ * @param vault Vault address (diamond proxy)
1564
+ * @param nonces Array of action nonces to cancel
1565
+ * @returns Transaction receipt
1566
+ */
1567
+ declare function vetoActions(signer: Signer, vault: string, nonces: bigint[]): Promise<ContractTransactionReceipt>;
1568
+
1569
+ /**
1570
+ * Curator swap helpers for Uniswap V3-compatible DEXes.
1571
+ *
1572
+ * Provides typed helpers to build CuratorAction objects and raw calldata for
1573
+ * Uniswap V3 exactInputSingle swaps, automatically resolving the correct router
1574
+ * and ABI variant (SwapRouter vs SwapRouter02) per chain.
1575
+ *
1576
+ * Supported chains and routers:
1577
+ * - Base (8453): SwapRouter02 0x2626... — NO deadline field
1578
+ * - Ethereum (1): SwapRouter 0xE592... — HAS deadline field
1579
+ * - Arbitrum (42161): SwapRouter 0xE592... — HAS deadline field
1580
+ * - Optimism (10): SwapRouter 0xE592... — HAS deadline field
1581
+ * - Flow EVM (747): FlowSwap V3 0xeEDC... — HAS deadline field
1582
+ *
1583
+ * @module curatorSwaps
1584
+ */
1585
+
1586
+ /**
1587
+ * Encode Uniswap V3 exactInputSingle calldata directly.
1588
+ * For curators who want raw calldata without the CuratorAction wrapper.
1589
+ *
1590
+ * Automatically selects the correct ABI variant (SwapRouter vs SwapRouter02)
1591
+ * based on the chainId. The deadline (for SwapRouter chains) is set to
1592
+ * `now + 20 minutes` to prevent stale transactions from executing.
1593
+ *
1594
+ * @param params.chainId EVM chain ID — must be present in UNISWAP_V3_ROUTERS
1595
+ * @param params.tokenIn Input token address
1596
+ * @param params.tokenOut Output token address
1597
+ * @param params.fee Pool fee tier: 100, 500, 3000, or 10000
1598
+ * @param params.amountIn Exact input amount (in tokenIn units)
1599
+ * @param params.minAmountOut Minimum acceptable output (slippage protection)
1600
+ * @param params.recipient Address to receive the output tokens (usually the vault)
1601
+ * @returns The router contract address and ABI-encoded calldata
1602
+ * @throws If no router is configured for the given chainId
1603
+ */
1604
+ declare function encodeUniswapV3SwapCalldata(params: {
1605
+ chainId: number;
1606
+ tokenIn: string;
1607
+ tokenOut: string;
1608
+ fee: number;
1609
+ amountIn: bigint;
1610
+ minAmountOut: bigint;
1611
+ recipient: string;
1612
+ }): {
1613
+ targetContract: string;
1614
+ swapCallData: string;
1615
+ };
1616
+ /**
1617
+ * Build a CuratorAction for a Uniswap V3 exactInputSingle swap.
1618
+ *
1619
+ * Automatically resolves the router address from UNISWAP_V3_ROUTERS and
1620
+ * selects the correct ABI struct (with or without deadline) based on chainId.
1621
+ *
1622
+ * The returned action is a `swap` variant ready to be passed to
1623
+ * `buildCuratorBatch` and then `submitActions`.
1624
+ *
1625
+ * @param params.chainId EVM chain ID — must be present in UNISWAP_V3_ROUTERS
1626
+ * @param params.tokenIn Input token address
1627
+ * @param params.tokenOut Output token address
1628
+ * @param params.fee Pool fee tier: 100, 500, 3000, or 10000
1629
+ * @param params.amountIn Exact input amount (in tokenIn units)
1630
+ * @param params.minAmountOut Minimum acceptable output (slippage protection)
1631
+ * @param params.recipient Address to receive output tokens (usually the vault)
1632
+ * @returns A typed CuratorAction ready for buildCuratorBatch
1633
+ * @throws If no router is configured for the given chainId
1634
+ *
1635
+ * @example
1636
+ * ```typescript
1637
+ * const action = buildUniswapV3Swap({
1638
+ * chainId: 8453,
1639
+ * tokenIn: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
1640
+ * tokenOut: '0x4200000000000000000000000000000000000006', // WETH
1641
+ * fee: 500, // 0.05% pool
1642
+ * amountIn: 150_000n, // 0.15 USDC (6 decimals)
1643
+ * minAmountOut: 1n, // accept any amount (set properly in production)
1644
+ * recipient: VAULT,
1645
+ * })
1646
+ * const batch = buildCuratorBatch([action])
1647
+ * await submitActions(signer, vault, batch)
1648
+ * ```
1649
+ */
1650
+ declare function buildUniswapV3Swap(params: {
1651
+ chainId: number;
1652
+ tokenIn: string;
1653
+ tokenOut: string;
1654
+ fee: number;
1655
+ amountIn: bigint;
1656
+ minAmountOut: bigint;
1657
+ recipient: string;
1658
+ }): CuratorAction;
1659
+
1660
+ /**
1661
+ * Vault topology helpers for the MoreVaults ethers.js v6 SDK.
1662
+ *
1663
+ * Resolves the cross-chain hub/spoke structure of a vault using the
1664
+ * MoreVaults OmniFactory contract (same address on every supported chain via CREATE3).
1665
+ */
1666
+
1667
+ declare const OMNI_FACTORY_ADDRESS = "0x7bDB8B17604b03125eFAED33cA0c55FBf856BB0C";
1668
+ interface VaultTopology {
1669
+ /**
1670
+ * Role of this vault on the chain you queried:
1671
+ * - 'hub' → this chain holds the TVL, users deposit here
1672
+ * - 'spoke' → this chain is a yield deployment; deposits go to the hub
1673
+ * - 'local' → single-chain vault, no cross-chain setup
1674
+ */
1675
+ role: "hub" | "spoke" | "local";
1676
+ /** Chain ID where the hub lives. Same as the queried chain when role='hub'. */
1677
+ hubChainId: number;
1678
+ /**
1679
+ * All spoke chain IDs registered under this hub.
1680
+ * Empty when role='local'.
1681
+ * Since vaults are CREATE3-deployed, the vault address is the same on all chains.
1682
+ */
1683
+ spokeChainIds: number[];
1684
+ }
1685
+ /**
1686
+ * Resolve the cross-chain topology of a vault: hub chain + all spoke chains.
1687
+ *
1688
+ * Works for hub vaults, spoke vaults, and local (single-chain) vaults.
1689
+ * Because MoreVaults uses CREATE3, the vault address is identical on every chain —
1690
+ * only the chain IDs differ.
1691
+ *
1692
+ * @param provider Connected to the chain you want to inspect
1693
+ * @param vault Vault address (same on all chains)
1694
+ * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)
1695
+ *
1696
+ * @example
1697
+ * // Querying from Base — will detect hub + Ethereum/Arbitrum spokes
1698
+ * const topo = await getVaultTopology(baseProvider, '0x8f740...')
1699
+ * // { role: 'hub', hubChainId: 8453, spokeChainIds: [1, 42161] }
1700
+ *
1701
+ * // Querying from Ethereum — same vault is a spoke there
1702
+ * const topo = await getVaultTopology(ethProvider, '0x8f740...')
1703
+ * // { role: 'spoke', hubChainId: 8453, spokeChainIds: [1, 42161] }
1704
+ */
1705
+ declare function getVaultTopology(provider: Provider, vault: string, factoryAddress?: string): Promise<VaultTopology>;
1706
+ /**
1707
+ * Resolve the FULL topology of a vault by querying the hub chain directly.
1708
+ *
1709
+ * Provide a provider connected to the hub chain for complete spoke data.
1710
+ * If you don't know which chain is the hub, call `getVaultTopology` first
1711
+ * from any chain and use the returned `hubChainId` to create the hub provider.
1712
+ *
1713
+ * @param hubChainProvider Provider connected to the hub chain
1714
+ * @param vault Vault address
1715
+ * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)
1716
+ */
1717
+ declare function getFullVaultTopology(hubChainProvider: Provider, vault: string, factoryAddress?: string): Promise<VaultTopology>;
1718
+ /**
1719
+ * Discover a vault's topology across all supported chains.
1720
+ *
1721
+ * Unlike `getVaultTopology` (which queries a single chain), this function
1722
+ * automatically iterates all supported chains when the initial query returns
1723
+ * `role: "local"`. This handles the case where the caller doesn't know which
1724
+ * chain the vault is deployed on, or when no provider is connected.
1725
+ *
1726
+ * If a `provider` is provided, it's tried first. If that returns "local",
1727
+ * every other supported chain is probed via public RPCs.
1728
+ * If no `provider` is provided, all chains are probed.
1729
+ *
1730
+ * Once a hub is found, `getFullVaultTopology` is called to get the complete
1731
+ * spoke list.
1732
+ *
1733
+ * @param vault Vault address (same on all chains via CREATE3)
1734
+ * @param provider Optional — provider for the "preferred" chain to try first
1735
+ * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)
1736
+ *
1737
+ * @example
1738
+ * // No wallet connected — discovers that 0x8f74... is hub on Base
1739
+ * const topo = await discoverVaultTopology('0x8f740...')
1740
+ * // { role: 'hub', hubChainId: 8453, spokeChainIds: [1, 42161] }
1741
+ */
1742
+ declare function discoverVaultTopology(vault: string, provider?: Provider | null, factoryAddress?: string): Promise<VaultTopology>;
1743
+ /**
1744
+ * Check if a wallet is connected to the hub chain for a given vault.
1745
+ * Useful for showing a "Switch to Base" prompt before deposit.
1746
+ *
1747
+ * @param currentChainId Chain ID the wallet is currently connected to
1748
+ * @param topology Result of getVaultTopology
1749
+ */
1750
+ declare function isOnHubChain(currentChainId: number, topology: VaultTopology): boolean;
1751
+ /**
1752
+ * Get all chain IDs where this vault is deployed (hub + all spokes).
1753
+ */
1754
+ declare function getAllVaultChainIds(topology: VaultTopology): number[];
1755
+
1756
+ /**
1757
+ * Vault distribution helpers for the MoreVaults ethers.js v6 SDK.
1758
+ *
1759
+ * Reads the cross-chain capital distribution of a vault: hub balance,
1760
+ * spoke balances, and aggregate totals.
1761
+ */
1762
+
1763
+ interface SpokeBalance {
1764
+ chainId: number;
1765
+ totalAssets: bigint;
1766
+ /** false if the RPC call to this spoke failed */
1767
+ isReachable: boolean;
1768
+ }
1769
+ interface VaultDistribution {
1770
+ hubChainId: number;
1771
+ /** Underlying token balance idle on the hub (not deployed to strategies) */
1772
+ hubLiquidBalance: bigint;
1773
+ /** Hub totalAssets minus hubLiquidBalance (capital in Morpho, Aave, etc.) */
1774
+ hubStrategyBalance: bigint;
1775
+ /** Hub vault totalAssets() */
1776
+ hubTotalAssets: bigint;
1777
+ /** What the hub's accounting thinks is deployed on spokes */
1778
+ spokesDeployedBalance: bigint;
1779
+ /** Actual per-spoke balances read directly from each spoke chain */
1780
+ spokeBalances: SpokeBalance[];
1781
+ /** hubTotalAssets + sum of reachable spoke totalAssets */
1782
+ totalActual: bigint;
1783
+ oracleAccountingEnabled: boolean;
1784
+ }
1785
+ /**
1786
+ * Read the full cross-chain capital distribution of a vault.
1787
+ *
1788
+ * Queries the hub for its status, then reads `totalAssets()` on each spoke
1789
+ * chain in parallel. Spoke calls are individually wrapped so a single
1790
+ * unreachable RPC never fails the entire call.
1791
+ *
1792
+ * @param hubProvider Provider connected to the hub chain
1793
+ * @param vault Vault address (same on all chains via CREATE3)
1794
+ * @param spokeProviders Map of chainId → Provider for each spoke chain
1795
+ *
1796
+ * @example
1797
+ * ```ts
1798
+ * const dist = await getVaultDistribution(baseProvider, VAULT, {
1799
+ * [1]: ethProvider,
1800
+ * [42161]: arbProvider,
1801
+ * })
1802
+ * console.log(`Hub liquid: ${dist.hubLiquidBalance}`)
1803
+ * console.log(`Total actual: ${dist.totalActual}`)
1804
+ * ```
1805
+ */
1806
+ declare function getVaultDistribution(hubProvider: Provider, vault: string, spokeProviders: Record<number, Provider>): Promise<VaultDistribution>;
1807
+ /**
1808
+ * Hub-only distribution — uses topology to discover spokes but does NOT
1809
+ * read spoke chains (no spoke providers needed).
1810
+ *
1811
+ * Returns hub data plus the list of spoke chainIds from the factory.
1812
+ * `spokeBalances` will be empty — callers must provide spoke providers to
1813
+ * `getVaultDistribution` for actual spoke reads.
1814
+ *
1815
+ * @param hubProvider Provider connected to the hub chain
1816
+ * @param vault Vault address
1817
+ *
1818
+ * @example
1819
+ * ```ts
1820
+ * const dist = await getVaultDistributionWithTopology(baseProvider, VAULT)
1821
+ * // dist.spokeBalances === [] (no spoke providers provided)
1822
+ * // dist.spokeChainIds tells you which chains to query
1823
+ * ```
1824
+ */
1825
+ declare function getVaultDistributionWithTopology(hubProvider: Provider, vault: string): Promise<VaultDistribution & {
1826
+ spokeChainIds: number[];
1827
+ }>;
1828
+
1829
+ /**
1830
+ * Spoke route helpers for the MoreVaults ethers.js v6 SDK.
1831
+ *
1832
+ * Provides functions to discover inbound/outbound cross-chain deposit and
1833
+ * redemption routes, and to quote LayerZero fees for those routes.
1834
+ */
1835
+ interface OutboundRoute {
1836
+ /** Chain ID where user can receive shares/assets */
1837
+ chainId: number;
1838
+ /** Whether this chain is the hub (direct redeem) or a spoke (shares bridged back) */
1839
+ routeType: "hub" | "spoke";
1840
+ /** LZ EID for this chain */
1841
+ eid: number;
1842
+ /** Native gas symbol */
1843
+ nativeSymbol: string;
1844
+ }
1845
+ interface InboundRoute {
1846
+ /** Internal route identifier from OFT_ROUTES (e.g. 'stgUSDC') — do NOT show to users */
1847
+ symbol: string;
1848
+ /** Chain ID where user sends from */
1849
+ spokeChainId: number;
1850
+ /**
1851
+ * How the deposit is executed:
1852
+ * - 'direct' → user is on the hub chain, vault uses standard ERC-4626 (depositSimple). No LZ fee.
1853
+ * - 'direct-async' → user is on the hub chain, vault uses async accounting (depositAsync). LZ fee required.
1854
+ * - 'oft-compose' → user is on a spoke chain, use depositFromSpoke via OFT compose. LZ fee required.
1855
+ */
1856
+ depositType: "direct" | "direct-async" | "oft-compose";
1857
+ /** OFT contract on spoke chain — pass as `spokeOFT` to depositFromSpoke. Null for direct deposits. */
1858
+ spokeOft: string | null;
1859
+ /** Token user must approve on spoke chain (ZeroAddress = native ETH) */
1860
+ spokeToken: string;
1861
+ /**
1862
+ * Human-readable symbol of the token the user needs to hold on the spoke chain.
1863
+ * For OFTAdapters this is the underlying token symbol (e.g. 'USDC', 'weETH').
1864
+ * For pure OFTs this is the OFT's own symbol (e.g. 'sUSDe', 'USDe').
1865
+ * Use this — not `symbol` — when displaying the token name to users.
1866
+ */
1867
+ sourceTokenSymbol: string;
1868
+ /** OFT contract on hub chain — receives tokens for the composer. Null for direct deposits. */
1869
+ hubOft: string | null;
1870
+ /** oftCmd to use in SendParam (0x01 for Stargate taxi, 0x for standard OFT) */
1871
+ oftCmd: string;
1872
+ /** LZ fee estimate in native wei of the SPOKE chain (not always ETH — e.g. FLOW on Flow EVM) */
1873
+ lzFeeEstimate: bigint;
1874
+ /** Native gas token symbol for the spoke chain — use this when displaying the fee */
1875
+ nativeSymbol: string;
1876
+ }
1877
+ interface InboundRouteWithBalance extends InboundRoute {
1878
+ /** User's token balance on the spoke chain */
1879
+ userBalance: bigint;
1880
+ }
1881
+ /** Native gas token symbol per chain ID — lzFeeEstimate is denominated in this token */
1882
+ declare const NATIVE_SYMBOL: Partial<Record<number, string>>;
1883
+ /**
1884
+ * Find all valid OFT inbound routes for a vault.
1885
+ *
1886
+ * Only returns routes for chains where the vault has a registered spoke —
1887
+ * this is required so the composer can send shares back to the user's chain.
1888
+ * The hub chain is always included as a 'direct' deposit option.
1889
+ *
1890
+ * Routes that revert on quoteSend() (no liquidity, no peer) are excluded.
1891
+ *
1892
+ * @param hubChainId Chain ID of the vault hub (e.g. 8453 for Base)
1893
+ * @param vault Vault address (to resolve registered spoke chains)
1894
+ * @param vaultAsset vault.asset() address on the hub chain
1895
+ * @param userAddress User address (used as receiver for fee quote)
1896
+ */
1897
+ declare function getInboundRoutes(hubChainId: number, vault: string, vaultAsset: string, userAddress: string): Promise<InboundRoute[]>;
1898
+ /**
1899
+ * Fetch user token balances for each inbound route in parallel.
1900
+ * Routes with native ETH as token (ZeroAddress) return the chain's ETH balance.
1901
+ *
1902
+ * @param routes Inbound routes from getInboundRoutes()
1903
+ * @param userAddress User wallet address
1904
+ */
1905
+ declare function getUserBalancesForRoutes(routes: InboundRoute[], userAddress: string): Promise<InboundRouteWithBalance[]>;
1906
+ /**
1907
+ * Find all outbound routes for a vault — chains where a user can receive
1908
+ * shares/assets when redeeming.
1909
+ *
1910
+ * The hub chain is always first (direct redeem). Spoke chains follow
1911
+ * (shares are bridged back via the composer).
1912
+ *
1913
+ * @param hubChainId Chain ID of the vault hub (e.g. 8453 for Base)
1914
+ * @param vault Vault address (to resolve registered spoke chains)
1915
+ */
1916
+ declare function getOutboundRoutes(hubChainId: number, vault: string): Promise<OutboundRoute[]>;
1917
+ /**
1918
+ * Quote the LayerZero native fee for a cross-chain deposit with a real amount.
1919
+ *
1920
+ * More precise than the `lzFeeEstimate` field on `InboundRoute`, which uses
1921
+ * a dummy 1 USDC amount.
1922
+ *
1923
+ * @param route An InboundRoute from `getInboundRoutes()`
1924
+ * @param hubChainId Chain ID of the vault hub (needed for LZ destination EID)
1925
+ * @param amount Real deposit amount in token decimals
1926
+ * @param userAddress User address (used as receiver for fee quote)
1927
+ * @returns Native fee in wei of the spoke chain's gas token, or 0n for direct deposits
1928
+ */
1929
+ declare function quoteRouteDepositFee(route: InboundRoute, hubChainId: number, amount: bigint, userAddress: string): Promise<bigint>;
784
1930
 
785
1931
  /**
786
1932
  * Cast an ethers Signer (e.g. from wagmi's useEthersSigner adapter) to
@@ -795,4 +1941,4 @@ declare function getVaultSummary(provider: Provider, vault: string): Promise<Vau
795
1941
  */
796
1942
  declare function asSdkSigner(signer: unknown): Signer;
797
1943
 
798
- export { ActionType, type ActionTypeValue, type AsyncRequestResult, type AsyncRequestStatus, type AsyncRequestStatusInfo, BRIDGE_ABI, CCManagerNotConfiguredError, CHAIN_IDS, CHAIN_ID_TO_EID, CONFIG_ABI, CapacityFullError, type CrossChainRequestInfo, type DepositBlockReason, type DepositEligibility, type DepositResult, EID_TO_CHAIN_ID, ERC20_ABI, EscrowNotConfiguredError, InsufficientLiquidityError, LZ_EIDS, LZ_ENDPOINT_ABI, LZ_TIMEOUTS, METADATA_ABI, type MaxWithdrawable, MissingEscrowAddressError, MoreVaultsError, NotHubVaultError, NotWhitelistedError, OFT_ABI, type RedeemResult, type UserBalances, type UserPosition, VAULT_ABI, type VaultAddresses, type VaultMetadata, type VaultMode, VaultPausedError, type VaultStatus, type VaultSummary, WrongChainError, asSdkSigner, bridgeAssetsToSpoke, bridgeSharesToHub, canDeposit, depositAsync, depositCrossChainOracleOn, depositFromSpoke, depositFromSpokeAsync, depositMultiAsset, depositSimple, ensureAllowance, executeCompose, getAsyncRequestStatus, getAsyncRequestStatusLabel, getMaxWithdrawable, getUserBalances, getUserPosition, getVaultMetadata, getVaultStatus, getVaultSummary, getWithdrawalRequest, isAsyncMode, mintAsync, preflightAsync, preflightRedeemLiquidity, preflightSync, previewDeposit, previewRedeem, quoteComposeFee, quoteDepositFromSpokeFee, quoteLzFee, redeemAsync, redeemShares, requestRedeem, smartDeposit, smartRedeem, withdrawAssets };
1944
+ export { ActionType, type ActionTypeValue, type AssetBalance, type AssetInfo, type AsyncRequestResult, type AsyncRequestStatus, type AsyncRequestStatusInfo, BRIDGE_ABI, BRIDGE_FACET_ABI, type BatchSwapParams, type BridgeParams, CCManagerNotConfiguredError, CHAIN_IDS, CHAIN_ID_TO_EID, CONFIG_ABI, CURATOR_CONFIG_ABI, CapacityFullError, type CrossChainRequestInfo, type CuratorAction, type CuratorVaultStatus, DEX_ABI, type DepositBlockReason, type DepositEligibility, type DepositResult, EID_TO_CHAIN_ID, ERC20_ABI, ERC4626_FACET_ABI, ERC7540_FACET_ABI, EscrowNotConfiguredError, type InboundRoute, type InboundRouteWithBalance, InsufficientLiquidityError, LZ_ADAPTER_ABI, LZ_EIDS, LZ_ENDPOINT_ABI, LZ_TIMEOUTS, METADATA_ABI, MULTICALL_ABI, type MaxWithdrawable, MissingEscrowAddressError, MoreVaultsError, type MultiChainUserPosition, NATIVE_SYMBOL, NotHubVaultError, NotWhitelistedError, OFT_ABI, OFT_ROUTES, OMNI_FACTORY_ADDRESS, type OutboundRoute, type PendingAction, REGISTRY_ABI, type RedeemResult, type SpokeBalance, type SpokeRedeemRoute, type SubmitActionsResult, type SwapParams, UNISWAP_V3_ROUTERS, type UserBalances, type UserPosition, VAULT_ABI, VAULT_ANALYSIS_ABI, type VaultAddresses, type VaultAnalysis, type VaultAssetBreakdown, type VaultDistribution, type VaultMetadata, type VaultMode, VaultPausedError, type VaultStatus, type VaultSummary, type VaultTopology, WrongChainError, asSdkSigner, bridgeAssetsToSpoke, bridgeSharesToHub, buildCuratorBatch, buildUniswapV3Swap, canDeposit, checkProtocolWhitelist, depositAsync, depositCrossChainOracleOn, depositFromSpoke, depositFromSpokeAsync, depositMultiAsset, depositSimple, detectStargateOft, discoverVaultTopology, encodeCuratorAction, encodeUniswapV3SwapCalldata, ensureAllowance, executeActions, executeCompose, getAllVaultChainIds, getAsyncRequestStatus, getAsyncRequestStatusLabel, getCuratorVaultStatus, getFullVaultTopology, getInboundRoutes, getMaxWithdrawable, getOutboundRoutes, getPendingActions, getUserBalances, getUserBalancesForRoutes, getUserPosition, getUserPositionMultiChain, getVaultAnalysis, getVaultAssetBreakdown, getVaultDistribution, getVaultDistributionWithTopology, getVaultMetadata, getVaultStatus, getVaultSummary, getVaultTopology, getWithdrawalRequest, isAsyncMode, isCurator, isOnHubChain, mintAsync, preflightAsync, preflightRedeemLiquidity, preflightSpokeDeposit, preflightSpokeRedeem, preflightSync, previewDeposit, previewRedeem, quoteComposeFee, quoteDepositFromSpokeFee, quoteLzFee, quoteRouteDepositFee, quoteShareBridgeFee, redeemAsync, redeemShares, requestRedeem, resolveRedeemAddresses, smartDeposit, smartRedeem, submitActions, vetoActions, waitForCompose, withdrawAssets };