@oydual31/more-vaults-sdk 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oydual31/more-vaults-sdk",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript SDK for MoreVaults protocol — viem/wagmi and ethers.js",
5
5
  "type": "module",
6
6
  "exports": {
package/src/viem/abis.ts CHANGED
@@ -451,6 +451,284 @@ export const OFT_ABI = [
451
451
  },
452
452
  ] as const
453
453
 
454
+ // ─────────────────────────────────────────────────────────────────────────────
455
+ // Curator Operations ABIs
456
+ // ─────────────────────────────────────────────────────────────────────────────
457
+
458
+ /**
459
+ * MulticallFacet ABI — curator action submission and execution with timelock.
460
+ */
461
+ export const MULTICALL_ABI = [
462
+ {
463
+ type: 'function',
464
+ name: 'submitActions',
465
+ inputs: [
466
+ { name: 'actionsData', type: 'bytes[]' },
467
+ ],
468
+ outputs: [{ name: 'nonce', type: 'uint256' }],
469
+ stateMutability: 'nonpayable',
470
+ },
471
+ {
472
+ type: 'function',
473
+ name: 'executeActions',
474
+ inputs: [
475
+ { name: 'actionsNonce', type: 'uint256' },
476
+ ],
477
+ outputs: [],
478
+ stateMutability: 'nonpayable',
479
+ },
480
+ {
481
+ type: 'function',
482
+ name: 'getPendingActions',
483
+ inputs: [
484
+ { name: 'actionsNonce', type: 'uint256' },
485
+ ],
486
+ outputs: [
487
+ { name: 'actionsData', type: 'bytes[]' },
488
+ { name: 'pendingUntil', type: 'uint256' },
489
+ ],
490
+ stateMutability: 'view',
491
+ },
492
+ {
493
+ type: 'function',
494
+ name: 'getCurrentNonce',
495
+ inputs: [],
496
+ outputs: [{ name: '', type: 'uint256' }],
497
+ stateMutability: 'view',
498
+ },
499
+ {
500
+ type: 'function',
501
+ name: 'vetoActions',
502
+ inputs: [
503
+ { name: 'actionsNonces', type: 'uint256[]' },
504
+ ],
505
+ outputs: [],
506
+ stateMutability: 'nonpayable',
507
+ },
508
+ ] as const
509
+
510
+ /**
511
+ * GenericDexFacet ABI — single and batch token swaps through any DEX aggregator.
512
+ */
513
+ export const DEX_ABI = [
514
+ {
515
+ type: 'function',
516
+ name: 'executeSwap',
517
+ inputs: [
518
+ {
519
+ name: 'params',
520
+ type: 'tuple',
521
+ components: [
522
+ { name: 'targetContract', type: 'address' },
523
+ { name: 'tokenIn', type: 'address' },
524
+ { name: 'tokenOut', type: 'address' },
525
+ { name: 'maxAmountIn', type: 'uint256' },
526
+ { name: 'minAmountOut', type: 'uint256' },
527
+ { name: 'swapCallData', type: 'bytes' },
528
+ ],
529
+ },
530
+ ],
531
+ outputs: [{ name: 'amountOut', type: 'uint256' }],
532
+ stateMutability: 'nonpayable',
533
+ },
534
+ {
535
+ type: 'function',
536
+ name: 'executeBatchSwap',
537
+ inputs: [
538
+ {
539
+ name: 'params',
540
+ type: 'tuple',
541
+ components: [
542
+ {
543
+ name: 'swaps',
544
+ type: 'tuple[]',
545
+ components: [
546
+ { name: 'targetContract', type: 'address' },
547
+ { name: 'tokenIn', type: 'address' },
548
+ { name: 'tokenOut', type: 'address' },
549
+ { name: 'maxAmountIn', type: 'uint256' },
550
+ { name: 'minAmountOut', type: 'uint256' },
551
+ { name: 'swapCallData', type: 'bytes' },
552
+ ],
553
+ },
554
+ ],
555
+ },
556
+ ],
557
+ outputs: [{ name: 'amountsOut', type: 'uint256[]' }],
558
+ stateMutability: 'nonpayable',
559
+ },
560
+ ] as const
561
+
562
+ /**
563
+ * BridgeFacet ABI — curator bridging and cross-chain request initiation.
564
+ * (extends the existing BRIDGE_ABI with curator-specific functions)
565
+ */
566
+ export const BRIDGE_FACET_ABI = [
567
+ {
568
+ type: 'function',
569
+ name: 'executeBridging',
570
+ inputs: [
571
+ { name: 'adapter', type: 'address' },
572
+ { name: 'token', type: 'address' },
573
+ { name: 'amount', type: 'uint256' },
574
+ { name: 'bridgeSpecificParams', type: 'bytes' },
575
+ ],
576
+ outputs: [],
577
+ stateMutability: 'payable',
578
+ },
579
+ {
580
+ type: 'function',
581
+ name: 'initVaultActionRequest',
582
+ inputs: [
583
+ { name: 'actionType', type: 'uint8' },
584
+ { name: 'actionCallData', type: 'bytes' },
585
+ { name: 'amountLimit', type: 'uint256' },
586
+ { name: 'extraOptions', type: 'bytes' },
587
+ ],
588
+ outputs: [{ name: 'guid', type: 'bytes32' }],
589
+ stateMutability: 'payable',
590
+ },
591
+ {
592
+ type: 'function',
593
+ name: 'executeRequest',
594
+ inputs: [
595
+ { name: 'guid', type: 'bytes32' },
596
+ ],
597
+ outputs: [],
598
+ stateMutability: 'nonpayable',
599
+ },
600
+ ] as const
601
+
602
+ /**
603
+ * ERC7540Facet ABI — async deposit and redeem operations on ERC7540 vaults.
604
+ */
605
+ export const ERC7540_FACET_ABI = [
606
+ {
607
+ type: 'function',
608
+ name: 'erc7540RequestDeposit',
609
+ inputs: [
610
+ { name: 'vault', type: 'address' },
611
+ { name: 'assets', type: 'uint256' },
612
+ ],
613
+ outputs: [{ name: 'requestId', type: 'uint256' }],
614
+ stateMutability: 'nonpayable',
615
+ },
616
+ {
617
+ type: 'function',
618
+ name: 'erc7540RequestRedeem',
619
+ inputs: [
620
+ { name: 'vault', type: 'address' },
621
+ { name: 'shares', type: 'uint256' },
622
+ ],
623
+ outputs: [{ name: 'requestId', type: 'uint256' }],
624
+ stateMutability: 'nonpayable',
625
+ },
626
+ {
627
+ type: 'function',
628
+ name: 'erc7540Deposit',
629
+ inputs: [
630
+ { name: 'vault', type: 'address' },
631
+ { name: 'assets', type: 'uint256' },
632
+ ],
633
+ outputs: [{ name: 'shares', type: 'uint256' }],
634
+ stateMutability: 'nonpayable',
635
+ },
636
+ {
637
+ type: 'function',
638
+ name: 'erc7540Redeem',
639
+ inputs: [
640
+ { name: 'vault', type: 'address' },
641
+ { name: 'shares', type: 'uint256' },
642
+ ],
643
+ outputs: [{ name: 'assets', type: 'uint256' }],
644
+ stateMutability: 'nonpayable',
645
+ },
646
+ ] as const
647
+
648
+ /**
649
+ * ConfigurationFacet ABI — extended with curator-relevant read functions.
650
+ * Augments the existing CONFIG_ABI with additional getters needed by curator dashboard.
651
+ */
652
+ export const CURATOR_CONFIG_ABI = [
653
+ {
654
+ type: 'function',
655
+ name: 'curator',
656
+ inputs: [],
657
+ outputs: [{ name: '', type: 'address' }],
658
+ stateMutability: 'view',
659
+ },
660
+ {
661
+ type: 'function',
662
+ name: 'timeLockPeriod',
663
+ inputs: [],
664
+ outputs: [{ name: '', type: 'uint256' }],
665
+ stateMutability: 'view',
666
+ },
667
+ {
668
+ type: 'function',
669
+ name: 'getAvailableAssets',
670
+ inputs: [],
671
+ outputs: [{ name: '', type: 'address[]' }],
672
+ stateMutability: 'view',
673
+ },
674
+ {
675
+ type: 'function',
676
+ name: 'getMaxSlippagePercent',
677
+ inputs: [],
678
+ outputs: [{ name: '', type: 'uint256' }],
679
+ stateMutability: 'view',
680
+ },
681
+ {
682
+ type: 'function',
683
+ name: 'getCrossChainAccountingManager',
684
+ inputs: [],
685
+ outputs: [{ name: '', type: 'address' }],
686
+ stateMutability: 'view',
687
+ },
688
+ {
689
+ type: 'function',
690
+ name: 'paused',
691
+ inputs: [],
692
+ outputs: [{ name: '', type: 'bool' }],
693
+ stateMutability: 'view',
694
+ },
695
+ ] as const
696
+
697
+ /**
698
+ * LzAdapter ABI — fee quoting for bridge and LZ Read operations.
699
+ */
700
+ export const LZ_ADAPTER_ABI = [
701
+ {
702
+ type: 'function',
703
+ name: 'quoteBridgeFee',
704
+ inputs: [
705
+ { name: 'bridgeSpecificParams', type: 'bytes' },
706
+ ],
707
+ outputs: [{ name: 'nativeFee', type: 'uint256' }],
708
+ stateMutability: 'view',
709
+ },
710
+ {
711
+ type: 'function',
712
+ name: 'quoteReadFee',
713
+ inputs: [
714
+ { name: 'vaults', type: 'address[]' },
715
+ { name: 'eids', type: 'uint32[]' },
716
+ { name: '_extraOptions', type: 'bytes' },
717
+ ],
718
+ outputs: [
719
+ {
720
+ name: 'fee',
721
+ type: 'tuple',
722
+ components: [
723
+ { name: 'nativeFee', type: 'uint256' },
724
+ { name: 'lzTokenFee', type: 'uint256' },
725
+ ],
726
+ },
727
+ ],
728
+ stateMutability: 'view',
729
+ },
730
+ ] as const
731
+
454
732
  /**
455
733
  * Minimal LZ Endpoint V2 ABI for compose queue management.
456
734
  * Used by the Stargate 2-TX flow to check compose status and execute pending composes.
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Curator / vault-manager read helpers for the MoreVaults SDK.
3
+ *
4
+ * All functions are read-only (no wallet needed) and use multicall for
5
+ * batched RPC efficiency.
6
+ */
7
+
8
+ import { type Address, type PublicClient, getAddress } from 'viem'
9
+ import { MULTICALL_ABI, CURATOR_CONFIG_ABI } from './abis.js'
10
+ import type { CuratorVaultStatus, PendingAction } from './types.js'
11
+
12
+ // ─────────────────────────────────────────────────────────────────────────────
13
+
14
+ /**
15
+ * Read a comprehensive status snapshot for the curator dashboard.
16
+ *
17
+ * Fetches in two batches (multicall) to minimise round trips:
18
+ * Batch 1: curator, timeLockPeriod, getMaxSlippagePercent, getCurrentNonce,
19
+ * getAvailableAssets, getCrossChainAccountingManager, paused
20
+ *
21
+ * @param publicClient Viem public client (must be on the vault's chain)
22
+ * @param vault Vault address (diamond proxy)
23
+ * @returns CuratorVaultStatus snapshot
24
+ */
25
+ export async function getCuratorVaultStatus(
26
+ publicClient: PublicClient,
27
+ vault: Address,
28
+ ): Promise<CuratorVaultStatus> {
29
+ const v = getAddress(vault)
30
+
31
+ const [
32
+ curator,
33
+ timeLockPeriod,
34
+ maxSlippagePercent,
35
+ currentNonce,
36
+ availableAssets,
37
+ lzAdapter,
38
+ paused,
39
+ ] = await publicClient.multicall({
40
+ contracts: [
41
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'curator' },
42
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'timeLockPeriod' },
43
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'getMaxSlippagePercent' },
44
+ { address: v, abi: MULTICALL_ABI, functionName: 'getCurrentNonce' },
45
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'getAvailableAssets' },
46
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'getCrossChainAccountingManager' },
47
+ { address: v, abi: CURATOR_CONFIG_ABI, functionName: 'paused' },
48
+ ],
49
+ allowFailure: false,
50
+ })
51
+
52
+ return {
53
+ curator: getAddress(curator as Address),
54
+ timeLockPeriod: timeLockPeriod as bigint,
55
+ maxSlippagePercent: maxSlippagePercent as bigint,
56
+ currentNonce: currentNonce as bigint,
57
+ availableAssets: (availableAssets as Address[]).map(getAddress),
58
+ lzAdapter: getAddress(lzAdapter as Address),
59
+ paused: paused as boolean,
60
+ }
61
+ }
62
+
63
+ // ─────────────────────────────────────────────────────────────────────────────
64
+
65
+ /**
66
+ * Fetch pending actions for a specific nonce and resolve whether they are
67
+ * executable (i.e. the timelock has expired).
68
+ *
69
+ * @param publicClient Viem public client (must be on the vault's chain)
70
+ * @param vault Vault address (diamond proxy)
71
+ * @param nonce Action nonce to query
72
+ * @returns PendingAction with isExecutable flag set
73
+ */
74
+ export async function getPendingActions(
75
+ publicClient: PublicClient,
76
+ vault: Address,
77
+ nonce: bigint,
78
+ ): Promise<PendingAction> {
79
+ const v = getAddress(vault)
80
+
81
+ const [actionsResult, block] = await Promise.all([
82
+ publicClient.readContract({
83
+ address: v,
84
+ abi: MULTICALL_ABI,
85
+ functionName: 'getPendingActions',
86
+ args: [nonce],
87
+ }),
88
+ publicClient.getBlock(),
89
+ ])
90
+
91
+ const [actionsData, pendingUntil] = actionsResult as [`0x${string}`[], bigint]
92
+ const isExecutable = pendingUntil > 0n && block.timestamp >= pendingUntil
93
+
94
+ return {
95
+ nonce,
96
+ actionsData,
97
+ pendingUntil,
98
+ isExecutable,
99
+ }
100
+ }
101
+
102
+ // ─────────────────────────────────────────────────────────────────────────────
103
+
104
+ /**
105
+ * Check whether a given address is the curator of the vault.
106
+ *
107
+ * @param publicClient Viem public client (must be on the vault's chain)
108
+ * @param vault Vault address (diamond proxy)
109
+ * @param address Address to check
110
+ * @returns true if address is the current curator
111
+ */
112
+ export async function isCurator(
113
+ publicClient: PublicClient,
114
+ vault: Address,
115
+ address: Address,
116
+ ): Promise<boolean> {
117
+ const curatorAddress = await publicClient.readContract({
118
+ address: getAddress(vault),
119
+ abi: CURATOR_CONFIG_ABI,
120
+ functionName: 'curator',
121
+ })
122
+
123
+ return getAddress(curatorAddress as Address) === getAddress(address)
124
+ }
package/src/viem/index.ts CHANGED
@@ -13,6 +13,12 @@ export {
13
13
  OFT_ABI,
14
14
  METADATA_ABI,
15
15
  LZ_ENDPOINT_ABI,
16
+ MULTICALL_ABI,
17
+ DEX_ABI,
18
+ BRIDGE_FACET_ABI,
19
+ ERC7540_FACET_ABI,
20
+ CURATOR_CONFIG_ABI,
21
+ LZ_ADAPTER_ABI,
16
22
  } from './abis'
17
23
 
18
24
  // --- Types ---
@@ -25,6 +31,13 @@ export type {
25
31
  ActionTypeValue,
26
32
  ComposeData,
27
33
  SpokeDepositResult,
34
+ SwapParams,
35
+ BatchSwapParams,
36
+ BridgeParams,
37
+ PendingAction,
38
+ SubmitActionsResult,
39
+ CuratorAction,
40
+ CuratorVaultStatus,
28
41
  } from './types'
29
42
  export { ActionType } from './types'
30
43
 
@@ -137,6 +150,13 @@ export type { VaultDistribution, SpokeBalance } from './distribution'
137
150
  export { getInboundRoutes, getUserBalancesForRoutes, getOutboundRoutes, quoteRouteDepositFee, NATIVE_SYMBOL } from './spokeRoutes'
138
151
  export type { InboundRoute, InboundRouteWithBalance, OutboundRoute } from './spokeRoutes'
139
152
 
153
+ // --- Curator Operations ---
154
+ export {
155
+ getCuratorVaultStatus,
156
+ getPendingActions,
157
+ isCurator,
158
+ } from './curatorStatus'
159
+
140
160
  // --- wagmi compatibility ---
141
161
  // Re-export viem's PublicClient type for wagmi compatibility.
142
162
  // wagmi's usePublicClient() returns a type that is structurally compatible
package/src/viem/types.ts CHANGED
@@ -98,3 +98,60 @@ export interface CrossChainRequestInfo {
98
98
  finalizationResult: bigint
99
99
  amountLimit: bigint
100
100
  }
101
+
102
+ // ─────────────────────────────────────────────────────────────────────────────
103
+ // Curator Operations Types
104
+ // ─────────────────────────────────────────────────────────────────────────────
105
+
106
+ export interface SwapParams {
107
+ targetContract: Address
108
+ tokenIn: Address
109
+ tokenOut: Address
110
+ maxAmountIn: bigint
111
+ minAmountOut: bigint
112
+ swapCallData: `0x${string}`
113
+ }
114
+
115
+ export interface BatchSwapParams {
116
+ swaps: SwapParams[]
117
+ }
118
+
119
+ export interface BridgeParams {
120
+ oftToken: Address
121
+ dstEid: number
122
+ amount: bigint
123
+ dstVault: Address
124
+ refundAddress: Address
125
+ }
126
+
127
+ export interface PendingAction {
128
+ nonce: bigint
129
+ actionsData: `0x${string}`[]
130
+ pendingUntil: bigint
131
+ isExecutable: boolean
132
+ }
133
+
134
+ export interface SubmitActionsResult {
135
+ txHash: `0x${string}`
136
+ nonce: bigint
137
+ }
138
+
139
+ export type CuratorAction =
140
+ | { type: 'swap'; params: SwapParams }
141
+ | { type: 'batchSwap'; params: BatchSwapParams }
142
+ | { type: 'erc4626Deposit'; vault: Address; assets: bigint }
143
+ | { type: 'erc4626Redeem'; vault: Address; shares: bigint }
144
+ | { type: 'erc7540RequestDeposit'; vault: Address; assets: bigint }
145
+ | { type: 'erc7540Deposit'; vault: Address; assets: bigint }
146
+ | { type: 'erc7540RequestRedeem'; vault: Address; shares: bigint }
147
+ | { type: 'erc7540Redeem'; vault: Address; shares: bigint }
148
+
149
+ export interface CuratorVaultStatus {
150
+ curator: Address
151
+ timeLockPeriod: bigint
152
+ maxSlippagePercent: bigint
153
+ currentNonce: bigint
154
+ availableAssets: Address[]
155
+ lzAdapter: Address
156
+ paused: boolean
157
+ }