@oydual31/more-vaults-sdk 0.3.3 → 0.4.1

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 (42) 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 +644 -0
  8. package/dist/react/index.cjs.map +1 -1
  9. package/dist/react/index.d.cts +111 -2
  10. package/dist/react/index.d.ts +111 -2
  11. package/dist/react/index.js +638 -3
  12. package/dist/react/index.js.map +1 -1
  13. package/dist/{spokeRoutes-BIafSbQ3.d.cts → spokeRoutes-B8Lnk-t4.d.cts} +191 -2
  14. package/dist/{spokeRoutes-BIafSbQ3.d.ts → spokeRoutes-B8Lnk-t4.d.ts} +191 -2
  15. package/dist/viem/index.d.cts +4 -192
  16. package/dist/viem/index.d.ts +4 -192
  17. package/package.json +1 -1
  18. package/src/ethers/abis.ts +92 -0
  19. package/src/ethers/chains.ts +191 -0
  20. package/src/ethers/crossChainFlows.ts +208 -0
  21. package/src/ethers/curatorMulticall.ts +195 -0
  22. package/src/ethers/curatorStatus.ts +319 -0
  23. package/src/ethers/curatorSwaps.ts +192 -0
  24. package/src/ethers/distribution.ts +156 -0
  25. package/src/ethers/index.ts +96 -1
  26. package/src/ethers/preflight.ts +225 -1
  27. package/src/ethers/redeemFlows.ts +160 -1
  28. package/src/ethers/spokeRoutes.ts +361 -0
  29. package/src/ethers/topology.ts +240 -0
  30. package/src/ethers/types.ts +95 -0
  31. package/src/ethers/userHelpers.ts +193 -0
  32. package/src/ethers/utils.ts +28 -0
  33. package/src/react/index.ts +25 -0
  34. package/src/react/useCuratorVaultStatus.ts +32 -0
  35. package/src/react/useExecuteActions.ts +23 -0
  36. package/src/react/useIsCurator.ts +30 -0
  37. package/src/react/usePendingActions.ts +33 -0
  38. package/src/react/useProtocolWhitelist.ts +30 -0
  39. package/src/react/useSubmitActions.ts +27 -0
  40. package/src/react/useVaultAnalysis.ts +32 -0
  41. package/src/react/useVaultAssetBreakdown.ts +32 -0
  42. package/src/react/useVetoActions.ts +23 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ethers/chains.ts","../../src/ethers/types.ts","../../src/ethers/abis.ts","../../src/ethers/errors.ts","../../src/ethers/preflight.ts","../../src/ethers/chainValidation.ts","../../src/ethers/utils.ts","../../src/ethers/depositFlows.ts","../../src/ethers/crossChainFlows.ts","../../src/ethers/redeemFlows.ts","../../src/ethers/userHelpers.ts","../../src/ethers/wagmiCompat.ts"],"names":["Contract","ZeroAddress","Interface","ensureAllowance","AbiCoder","zeroPadValue","MULTICALL3_ADDRESS","MULTICALL3_ABI"],"mappings":"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","file":"index.cjs","sourcesContent":["/** EVM Chain IDs for chains supported by MoreVaults */\nexport const CHAIN_IDS = {\n flowEVMMainnet: 747,\n flowEVMTestnet: 545,\n arbitrum: 42161,\n base: 8453,\n ethereum: 1,\n} as const;\n\n/**\n * LayerZero Endpoint IDs (EID) for chains supported by MoreVaults.\n * Verified on-chain via MoreVaults OmniFactory.localEid() on each chain.\n * - flowMainnet: 30336 (0x7680) — confirmed from factory + LZ endpoint on Flow EVM mainnet\n */\nexport const LZ_EIDS = {\n flowMainnet: 30336,\n flowTestnet: 30333,\n arbitrum: 30110,\n base: 30184,\n ethereum: 30101,\n} as const;\n\n/** LayerZero EID → EVM Chain ID */\nexport const EID_TO_CHAIN_ID: Record<number, number> = {\n [LZ_EIDS.flowMainnet]: CHAIN_IDS.flowEVMMainnet,\n [LZ_EIDS.flowTestnet]: CHAIN_IDS.flowEVMTestnet,\n [LZ_EIDS.arbitrum]: CHAIN_IDS.arbitrum,\n [LZ_EIDS.base]: CHAIN_IDS.base,\n [LZ_EIDS.ethereum]: CHAIN_IDS.ethereum,\n};\n\n/** EVM Chain ID → LayerZero EID */\nexport const CHAIN_ID_TO_EID: Record<number, number> = {\n [CHAIN_IDS.flowEVMMainnet]: LZ_EIDS.flowMainnet,\n [CHAIN_IDS.flowEVMTestnet]: LZ_EIDS.flowTestnet,\n [CHAIN_IDS.arbitrum]: LZ_EIDS.arbitrum,\n [CHAIN_IDS.base]: LZ_EIDS.base,\n [CHAIN_IDS.ethereum]: LZ_EIDS.ethereum,\n};\n\n/**\n * Recommended timeouts for cross-chain operations (milliseconds).\n * UIs should show a progress indicator and NOT timeout before these values.\n */\nexport const LZ_TIMEOUTS = {\n /** Poll interval between balance/event checks */\n POLL_INTERVAL: 30_000,\n /** Standard OFT bridge (shares or assets, non-Stargate) */\n OFT_BRIDGE: 900_000, // 15 min\n /** Stargate bridge (USDC, USDT, WETH) — slower due to pool mechanics */\n STARGATE_BRIDGE: 1_800_000, // 30 min\n /** LZ Read callback (async vault actions) */\n LZ_READ_CALLBACK: 900_000, // 15 min\n /** Compose delivery to hub (deposit from spoke) */\n COMPOSE_DELIVERY: 2_700_000, // 45 min\n /** Full spoke→hub→spoke redeem (all steps combined) */\n FULL_SPOKE_REDEEM: 3_600_000, // 60 min\n} as const;\n","import type { Signer, Provider, ContractTransactionReceipt } from \"ethers\";\n\n/** Addresses involved in vault operations. */\nexport interface VaultAddresses {\n /** Hub vault (diamond proxy) address. */\n vault: string;\n /** MoreVaultsEscrow address for cross-chain locking. */\n escrow?: string;\n /** OFTAdapter address for share token bridging (cross-chain only). */\n shareOFT?: string;\n /** OFT address for USDC bridging (cross-chain only). */\n usdcOFT?: string;\n /**\n * Expected EVM chain ID of the hub. When provided, SDK functions will\n * throw a clear WrongChainError if the signer is on a different chain.\n * Prevents silent failures when MetaMask is connected to the wrong network.\n */\n hubChainId?: number;\n}\n\n/** Result of a synchronous deposit or mint. */\nexport interface DepositResult {\n receipt: ContractTransactionReceipt;\n /** Number of vault shares minted. */\n shares: bigint;\n}\n\n/** Result of a synchronous redeem or withdraw. */\nexport interface RedeemResult {\n receipt: ContractTransactionReceipt;\n /** Number of underlying assets returned. */\n assets: bigint;\n}\n\n/** Result of an asynchronous cross-chain request. */\nexport interface AsyncRequestResult {\n receipt: ContractTransactionReceipt;\n /** bytes32 request GUID for tracking fulfillment. */\n guid: string;\n}\n\n/**\n * ActionType enum matching MoreVaultsLib.ActionType on-chain values.\n *\n * DEPOSIT = 0, MINT = 1, WITHDRAW = 2, REDEEM = 3,\n * MULTI_ASSETS_DEPOSIT = 4, ACCRUE_FEES = 5\n */\nexport const ActionType = {\n DEPOSIT: 0,\n MINT: 1,\n WITHDRAW: 2,\n REDEEM: 3,\n MULTI_ASSETS_DEPOSIT: 4,\n ACCRUE_FEES: 5,\n} as const;\n\nexport type ActionTypeValue = (typeof ActionType)[keyof typeof ActionType];\n\n/** Cross-chain request info returned by getRequestInfo. */\nexport interface CrossChainRequestInfo {\n initiator: string;\n timestamp: bigint;\n actionType: number;\n actionCallData: string;\n fulfilled: boolean;\n finalized: boolean;\n refunded: boolean;\n totalAssets: bigint;\n finalizationResult: bigint;\n amountLimit: bigint;\n}\n\nexport type { Signer, Provider, ContractTransactionReceipt };\n","/**\n * Human-readable ABI fragments for MoreVaults diamond facets.\n * Extracted from compiled artifacts in out/.\n */\n\nexport const VAULT_ABI = [\n // ERC4626 core\n \"function deposit(uint256 assets, address receiver) returns (uint256 shares)\",\n \"function mint(uint256 shares, address receiver) returns (uint256 assets)\",\n \"function withdraw(uint256 assets, address receiver, address owner) returns (uint256 shares)\",\n \"function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)\",\n\n // Multi-asset deposit\n \"function deposit(address[] tokens, uint256[] assets, address receiver, uint256 minAmountOut) payable returns (uint256 shares)\",\n\n // Withdrawal queue\n \"function requestRedeem(uint256 shares, address onBehalfOf)\",\n \"function requestWithdraw(uint256 assets, address onBehalfOf)\",\n \"function clearRequest()\",\n \"function getWithdrawalRequest(address _owner) view returns (uint256 shares, uint256 timelockEndsAt)\",\n\n // Views\n \"function totalAssets() view returns (uint256)\",\n \"function totalSupply() view returns (uint256)\",\n \"function balanceOf(address account) view returns (uint256)\",\n \"function asset() view returns (address)\",\n \"function convertToShares(uint256 assets) view returns (uint256)\",\n \"function convertToAssets(uint256 shares) view returns (uint256)\",\n \"function previewDeposit(uint256 assets) view returns (uint256)\",\n \"function previewRedeem(uint256 shares) view returns (uint256)\",\n \"function paused() view returns (bool)\",\n\n // Events\n \"event Deposit(address indexed sender, address indexed owner, address[] tokens, uint256[] assets, uint256 shares)\",\n \"event Transfer(address indexed from, address indexed to, uint256 value)\",\n \"event WithdrawRequestCreated(address requester, uint256 sharesAmount, uint256 endsAt)\",\n \"event WithdrawRequestFulfilled(address requester, address receiver, uint256 sharesAmount, uint256 assetAmount)\",\n] as const;\n\nexport const BRIDGE_ABI = [\n \"function initVaultActionRequest(uint8 actionType, bytes actionCallData, uint256 amountLimit, bytes extraOptions) payable returns (bytes32 guid)\",\n \"function getRequestInfo(bytes32 guid) view returns (tuple(address initiator, uint64 timestamp, uint8 actionType, bytes actionCallData, bool fulfilled, bool finalized, bool refunded, uint256 totalAssets, uint256 finalizationResult, uint256 amountLimit))\",\n \"function getFinalizationResult(bytes32 guid) view returns (uint256 result)\",\n \"function oraclesCrossChainAccounting() view returns (bool)\",\n \"function quoteAccountingFee(bytes extraOptions) view returns (uint256 nativeFee)\",\n \"function accountingBridgeFacet() view returns (uint256 sum, bool isPositive)\",\n] as const;\n\nexport const CONFIG_ABI = [\n \"function getEscrow() view returns (address escrow)\",\n \"function getCrossChainAccountingManager() view returns (address)\",\n \"function isHub() view returns (bool)\",\n \"function getWithdrawalQueueStatus() view returns (bool)\",\n \"function getWithdrawalTimelock() view returns (uint64)\",\n \"function getWithdrawalFee() view returns (uint96)\",\n \"function getMaxWithdrawalDelay() view returns (uint32)\",\n \"function getAvailableAssets() view returns (address[])\",\n \"function getDepositableAssets() view returns (address[])\",\n \"function depositCapacity() view returns (uint256)\",\n \"function fee() view returns (uint96)\",\n \"function feeRecipient() view returns (address)\",\n \"function paused() view returns (bool)\",\n \"function maxDeposit(address receiver) view returns (uint256)\",\n] as const;\n\nexport const METADATA_ABI = [\n \"function name() view returns (string)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n] as const;\n\nexport const ERC20_ABI = [\n \"function approve(address spender, uint256 amount) returns (bool)\",\n \"function allowance(address owner, address spender) view returns (uint256)\",\n \"function balanceOf(address account) view returns (uint256)\",\n \"function transfer(address to, uint256 amount) returns (bool)\",\n] as const;\n\nexport const OFT_ABI = [\n \"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)\",\n \"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))\",\n] as const;\n\nexport const LZ_ENDPOINT_ABI = [\n \"function composeQueue(address from, address to, bytes32 guid, uint16 index) view returns (bytes32 messageHash)\",\n \"function lzCompose(address _from, address _to, bytes32 _guid, uint16 _index, bytes _message, bytes _extraData) payable\",\n] as const;\n","/**\n * Typed error classes for the MoreVaults SDK.\n *\n * Frontend code can use instanceof checks to handle errors programmatically:\n * catch (e) {\n * if (e instanceof InsufficientLiquidityError) { ... }\n * }\n */\n\nexport class MoreVaultsError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MoreVaultsError'\n }\n}\n\nexport class VaultPausedError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`)\n this.name = 'VaultPausedError'\n }\n}\n\nexport class CapacityFullError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} has reached deposit capacity. No more deposits accepted.`)\n this.name = 'CapacityFullError'\n }\n}\n\nexport class NotWhitelistedError extends MoreVaultsError {\n constructor(vault: string, user: string) {\n super(`[MoreVaults] Address ${user} is not whitelisted to deposit in vault ${vault}.`)\n this.name = 'NotWhitelistedError'\n }\n}\n\nexport class InsufficientLiquidityError extends MoreVaultsError {\n hubLiquid: bigint\n required: bigint\n constructor(vault: string, hubLiquid: bigint, required: bigint) {\n super(\n `[MoreVaults] Insufficient hub liquidity for redeem.\\n` +\n ` Hub liquid balance : ${hubLiquid}\\n` +\n ` Estimated required : ${required}\\n` +\n `Submitting this redeem will waste the LayerZero fee — the request will be auto-refunded.\\n` +\n `Ask the vault curator to repatriate liquidity from spoke chains first.`\n )\n this.name = 'InsufficientLiquidityError'\n this.hubLiquid = hubLiquid\n this.required = required\n }\n}\n\nexport class CCManagerNotConfiguredError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] CCManager not configured on vault ${vault}. Call setCrossChainAccountingManager(ccManagerAddress) as vault owner first.`)\n this.name = 'CCManagerNotConfiguredError'\n }\n}\n\nexport class EscrowNotConfiguredError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Escrow not configured for vault ${vault}. The registry must have an escrow set for this vault.`)\n this.name = 'EscrowNotConfiguredError'\n }\n}\n\nexport class NotHubVaultError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} is not a hub vault. Async flows (D4/D5/R5) only work on hub vaults.`)\n this.name = 'NotHubVaultError'\n }\n}\n\nexport class MissingEscrowAddressError extends MoreVaultsError {\n constructor() {\n super(`[MoreVaults] This flow requires an escrow address. Set VaultAddresses.escrow before calling async deposit/redeem flows.`)\n this.name = 'MissingEscrowAddressError'\n }\n}\n\nexport class WrongChainError extends MoreVaultsError {\n constructor(currentChainId: number, expectedChainId: number) {\n super(\n `Wrong network: wallet is on chain ${currentChainId}, but the vault hub requires chain ${expectedChainId}. Switch networks before proceeding.`,\n )\n this.name = 'WrongChainError'\n }\n}\n","/**\n * Pre-flight validation helpers for MoreVaults ethers.js v6 SDK flows.\n *\n * Each function reads on-chain state and throws a descriptive error BEFORE\n * the actual contract call, so developers see a clear, actionable message\n * instead of a raw VM revert.\n */\n\nimport { Contract, ZeroAddress } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { CONFIG_ABI, BRIDGE_ABI, VAULT_ABI, ERC20_ABI } from \"./abis\";\nimport { InsufficientLiquidityError } from \"./errors\";\n\n/**\n * Pre-flight checks for async cross-chain flows (D4 / D5 / R5).\n *\n * Validates that:\n * 1. The CCManager is configured on the vault.\n * 2. An escrow is registered in the vault's registry.\n * 3. The vault is a hub (required for async flows).\n * 4. The vault does NOT have oracle-based cross-chain accounting enabled\n * (oracle-on vaults should use depositSimple / depositCrossChainOracleOn).\n * 5. The vault is not paused.\n *\n * All reads that are independent of each other are executed in parallel via\n * Promise.all to minimise latency.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n * @param escrow Escrow address from VaultAddresses\n */\nexport async function preflightAsync(\n provider: Provider,\n vault: string,\n escrow: string\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n // Parallel read: ccManager, escrow, isHub, oraclesCrossChainAccounting, paused\n const [ccManager, registeredEscrow, isHub, oraclesEnabled, isPaused] =\n await Promise.all([\n config.getCrossChainAccountingManager() as Promise<string>,\n config.getEscrow() as Promise<string>,\n config.isHub() as Promise<boolean>,\n bridge.oraclesCrossChainAccounting() as Promise<boolean>,\n config.paused() as Promise<boolean>,\n ]);\n\n if (ccManager === ZeroAddress) {\n throw new Error(\n `[MoreVaults] CCManager not configured on vault ${vault}. Call setCrossChainAccountingManager(ccManagerAddress) as vault owner first.`\n );\n }\n\n if (registeredEscrow === ZeroAddress) {\n throw new Error(\n `[MoreVaults] Escrow not configured for vault ${vault}. The registry must have an escrow set for this vault.`\n );\n }\n\n if (!isHub) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is not a hub vault. Async flows (D4/D5/R5) only work on hub vaults.`\n );\n }\n\n if (oraclesEnabled) {\n throw new Error(\n `[MoreVaults] Vault ${vault} has oracle-based cross-chain accounting enabled. Use depositSimple/depositCrossChainOracleOn instead of async flows.`\n );\n }\n\n if (isPaused) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`\n );\n }\n}\n\n/**\n * Pre-flight liquidity check for async redeem (R5).\n *\n * Reads the hub's liquid balance of the underlying token and compares it\n * against the assets the user expects to receive. If the hub does not hold\n * enough liquid assets the redeem will be auto-refunded after the LZ round-trip,\n * wasting the LayerZero fee.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n * @param shares Shares the user intends to redeem\n */\nexport async function preflightRedeemLiquidity(\n provider: Provider,\n vault: string,\n shares: bigint\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n // Check if this is a hub vault without oracle accounting.\n // Only those vaults can have liquidity stranded on spoke chains.\n const [isHub, oraclesEnabled]: [boolean, boolean] = await Promise.all([\n config.isHub(),\n bridge.oraclesCrossChainAccounting(),\n ]);\n\n // Non-hub vaults and oracle-on hubs hold all redeemable assets locally —\n // no liquidity gap is possible, so skip the check.\n if (!isHub || oraclesEnabled) return;\n\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const underlying: string = await vaultContract.asset();\n\n const underlyingContract = new Contract(underlying, ERC20_ABI, provider);\n // NOTE: previewRedeem reverts on async cross-chain vaults (disabled by design).\n // convertToAssets is always safe and gives a correct lower-bound estimate.\n const [hubLiquid, assetsNeeded]: [bigint, bigint] = await Promise.all([\n underlyingContract.balanceOf(vault),\n vaultContract.convertToAssets(shares),\n ]);\n\n if (hubLiquid < assetsNeeded) {\n throw new InsufficientLiquidityError(vault, hubLiquid, assetsNeeded);\n }\n}\n\n/**\n * Pre-flight checks for synchronous deposit flows (D1 / D3).\n *\n * Validates that:\n * 1. The vault is not paused.\n * 2. The vault still has deposit capacity (maxDeposit > 0).\n *\n * Both reads are executed in parallel.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n */\nexport async function preflightSync(\n provider: Provider,\n vault: string\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n\n // Run paused and maxDeposit in parallel.\n // maxDeposit(ZeroAddress) may REVERT on whitelisted vaults — catch separately.\n const [isPaused, depositCapResult] = await Promise.all([\n config.paused() as Promise<boolean>,\n (config.maxDeposit(ZeroAddress) as Promise<bigint>).catch(() => null as null),\n ]);\n\n if (isPaused) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`\n );\n }\n\n // null means maxDeposit reverted → whitelist vault — skip capacity check\n // (the user may still be whitelisted; canDeposit will do user-specific check)\n if (depositCapResult !== null && depositCapResult === 0n) {\n throw new Error(\n `[MoreVaults] Vault ${vault} has reached deposit capacity. No more deposits accepted.`\n );\n }\n}\n","import type { Signer } from 'ethers'\nimport { WrongChainError } from './errors'\n\n/**\n * Validate that the signer is connected to the expected chain.\n * Only validates if hubChainId is provided — opt-in, non-breaking.\n */\nexport async function validateWalletChain(signer: Signer, hubChainId?: number): Promise<void> {\n if (!hubChainId) return\n const network = await signer.provider?.getNetwork()\n if (!network) return\n const current = Number(network.chainId)\n if (current !== hubChainId) {\n throw new WrongChainError(current, hubChainId)\n }\n}\n","/**\n * Utility helpers for the MoreVaults ethers.js v6 SDK.\n *\n * All reads use Provider (read-only). Writes use Signer.\n */\n\nimport { Contract, Interface, ZeroAddress } from \"ethers\";\nimport type { Provider, Signer } from \"ethers\";\nimport { BRIDGE_ABI, CONFIG_ABI, ERC20_ABI, VAULT_ABI } from \"./abis\";\n\n// Multicall3 — deployed at the same address on every EVM chain\nconst MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\nconst MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n] as const;\nimport type { CrossChainRequestInfo } from \"./types\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type VaultMode =\n | \"local\" // single-chain vault, no cross-chain\n | \"cross-chain-oracle\" // hub with oracle-based accounting (sync)\n | \"cross-chain-async\" // hub with off-chain accounting (async, D4/D5/R5)\n | \"paused\" // vault is paused\n | \"full\"; // deposit capacity reached\n\nexport interface VaultStatus {\n /** Vault operating mode — determines which SDK flow to use */\n mode: VaultMode;\n /** Which deposit function to call given the current configuration */\n recommendedDepositFlow: \"depositSimple\" | \"depositAsync\" | \"mintAsync\" | \"none\";\n /** Which redeem function to call given the current configuration */\n recommendedRedeemFlow: \"redeemShares\" | \"redeemAsync\" | \"none\";\n\n // ── Configuration ──────────────────────────────────────────────────────────\n isHub: boolean;\n isPaused: boolean;\n oracleAccountingEnabled: boolean;\n\n /** address(0) means CCManager is not set — async flows will fail */\n ccManager: string;\n /** address(0) means escrow is not configured in the registry */\n escrow: string;\n\n // ── Withdrawal queue ───────────────────────────────────────────────────────\n withdrawalQueueEnabled: boolean;\n /** Timelock duration in seconds (0 = no timelock) */\n withdrawalTimelockSeconds: bigint;\n\n // ── Capacity ───────────────────────────────────────────────────────────────\n /**\n * Remaining deposit capacity in underlying token decimals.\n * `type(uint256).max` = no cap configured (unlimited).\n * `0n` = vault is full — no more deposits accepted.\n * If `depositAccessRestricted = true`, this value is `type(uint256).max` but\n * deposits are still gated by whitelist or other access control.\n */\n remainingDepositCapacity: bigint;\n /**\n * True when `maxDeposit(address(0))` reverted, indicating the vault uses\n * whitelist or other access control to restrict who can deposit.\n */\n depositAccessRestricted: boolean;\n\n // ── Vault metrics ──────────────────────────────────────────────────────────\n underlying: string;\n totalAssets: bigint;\n totalSupply: bigint;\n /** Vault share token decimals. Use this for display — never hardcode 18. */\n decimals: number;\n /**\n * Price of 1 full share expressed in underlying token units.\n * = convertToAssets(10^decimals). Grows over time as the vault earns yield.\n */\n sharePrice: bigint;\n /**\n * Underlying token balance held directly on the hub chain.\n * This is the only portion that can be paid out to redeeming users immediately.\n * (= ERC-20.balanceOf(vault) on the hub)\n */\n hubLiquidBalance: bigint;\n /**\n * Approximate value deployed to spoke chains (totalAssets − hubLiquidBalance).\n * These funds are NOT immediately redeemable — the vault curator must\n * call executeBridging to repatriate them before large redeems can succeed.\n */\n spokesDeployedBalance: bigint;\n /**\n * Maximum assets that can be redeemed right now without curator intervention.\n * - For hub vaults: equals `hubLiquidBalance`.\n * - For local/oracle vaults: equals `totalAssets`.\n */\n maxImmediateRedeemAssets: bigint;\n\n // ── Issues — empty when everything is correctly configured ─────────────────\n /**\n * Human-readable list of configuration problems that would cause transactions\n * to fail. Empty array = vault is ready to use.\n */\n issues: string[];\n}\n\n/**\n * Ensure the spender has sufficient ERC-20 allowance; approve if not.\n *\n * @param signer Wallet signer with account attached\n * @param provider Read-only provider for allowance checks\n * @param token ERC-20 token address\n * @param spender Address to approve\n * @param amount Minimum required allowance\n */\nexport async function ensureAllowance(\n signer: Signer,\n provider: Provider,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20Read = new Contract(token, ERC20_ABI, provider);\n const current: bigint = await erc20Read.allowance(owner, spender);\n if (current < amount) {\n const erc20Write = new Contract(token, ERC20_ABI, signer);\n const tx = await erc20Write.approve(spender, amount);\n await tx.wait();\n }\n}\n\n/**\n * Quote the LayerZero native fee required for async vault actions.\n *\n * @param provider Read-only provider\n * @param vault Vault address (diamond proxy)\n * @param extraOptions Optional LZ extra options bytes (default 0x)\n * @returns Required native fee in wei\n */\nexport async function quoteLzFee(\n provider: Provider,\n vault: string,\n extraOptions: string = \"0x\"\n): Promise<bigint> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n const fee: bigint = await bridge.quoteAccountingFee(extraOptions);\n return fee;\n}\n\n/**\n * Check if a vault is operating in async mode (cross-chain hub with oracle OFF).\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns true if the vault requires async cross-chain flows\n */\nexport async function isAsyncMode(\n provider: Provider,\n vault: string\n): Promise<boolean> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [isHub, oraclesEnabled]: [boolean, boolean] = await Promise.all([\n config.isHub(),\n bridge.oraclesCrossChainAccounting(),\n ]);\n\n if (!isHub) return false;\n return !oraclesEnabled;\n}\n\n/**\n * Poll for async request completion status.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param guid Request GUID returned by the async flow\n * @returns Whether the request is fulfilled, finalized, and the result\n */\nexport async function getAsyncRequestStatus(\n provider: Provider,\n vault: string,\n guid: string\n): Promise<{ fulfilled: boolean; finalized: boolean; result: bigint }> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [info, finalizationResult]: [CrossChainRequestInfo, bigint] =\n await Promise.all([\n bridge.getRequestInfo(guid),\n bridge.getFinalizationResult(guid),\n ]);\n\n return {\n fulfilled: info.fulfilled,\n finalized: info.finalized,\n result: finalizationResult,\n };\n}\n\n/**\n * Read the full configuration and operational status of a vault.\n *\n * All independent reads are fired in parallel.\n *\n * @param provider Read-only provider\n * @param vault Vault address (diamond proxy)\n * @returns Full vault status snapshot\n */\nexport async function getVaultStatus(\n provider: Provider,\n vault: string\n): Promise<VaultStatus> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const configIface = new Interface(CONFIG_ABI as unknown as string[]);\n const bridgeIface = new Interface(BRIDGE_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // ── Batch 1: 12 calls → 1 eth_call via Multicall3.aggregate3 ─────────────\n const b1Calls = [\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"isHub\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"paused\") },\n { target: vault, allowFailure: false, callData: bridgeIface.encodeFunctionData(\"oraclesCrossChainAccounting\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getCrossChainAccountingManager\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getEscrow\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getWithdrawalQueueStatus\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getWithdrawalTimelock\") },\n // allowFailure=true: maxDeposit reverts on whitelisted vaults with address(0)\n { target: vault, allowFailure: true, callData: configIface.encodeFunctionData(\"maxDeposit\", [ZeroAddress]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"totalAssets\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"totalSupply\") },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const isHub = configIface.decodeFunctionResult(\"isHub\", b1[0].returnData)[0] as boolean;\n const isPaused = configIface.decodeFunctionResult(\"paused\", b1[1].returnData)[0] as boolean;\n const oraclesEnabled = bridgeIface.decodeFunctionResult(\"oraclesCrossChainAccounting\", b1[2].returnData)[0] as boolean;\n const ccManager = configIface.decodeFunctionResult(\"getCrossChainAccountingManager\", b1[3].returnData)[0] as string;\n const escrow = configIface.decodeFunctionResult(\"getEscrow\", b1[4].returnData)[0] as string;\n const withdrawalQueueEnabled = configIface.decodeFunctionResult(\"getWithdrawalQueueStatus\", b1[5].returnData)[0] as boolean;\n const withdrawalTimelockSeconds = configIface.decodeFunctionResult(\"getWithdrawalTimelock\", b1[6].returnData)[0] as bigint;\n // null sentinel: reverted means whitelist/ACL\n const maxDepositRaw = b1[7].success\n ? configIface.decodeFunctionResult(\"maxDeposit\", b1[7].returnData)[0] as bigint\n : null;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[8].returnData)[0] as string;\n const totalAssets = vaultIface.decodeFunctionResult(\"totalAssets\", b1[9].returnData)[0] as bigint;\n const totalSupply = vaultIface.decodeFunctionResult(\"totalSupply\", b1[10].returnData)[0] as bigint;\n const decimalsRaw = decimalsIface.decodeFunctionResult(\"decimals\", b1[11].returnData)[0];\n const decimalsNum = Number(decimalsRaw);\n const oneShare = 10n ** BigInt(decimalsNum);\n\n // ── Batch 2: 2 calls → 1 eth_call (depends on underlying + decimals) ─────\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n const b2Calls = [\n { target: underlying, allowFailure: false, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [vault]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"convertToAssets\", [oneShare]) },\n ];\n\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const hubLiquidBalance = erc20Iface.decodeFunctionResult(\"balanceOf\", b2[0].returnData)[0] as bigint;\n const sharePrice = vaultIface.decodeFunctionResult(\"convertToAssets\", b2[1].returnData)[0] as bigint;\n\n const spokesDeployedBalance: bigint = totalAssets > hubLiquidBalance ? totalAssets - hubLiquidBalance : 0n;\n\n // null = maxDeposit reverted.\n // For cross-chain-async hubs this is expected — the contract reverts with\n // NotAnERC4626CompatibleVault because maxDeposit is not meaningful in async mode.\n // Only treat the revert as \"whitelist/ACL\" when the vault is NOT a hub.\n const MAX_UINT256 = BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');\n const isCrossChainAsync = isHub && !oraclesEnabled;\n const depositAccessRestricted = maxDepositRaw === null && !isCrossChainAsync;\n const effectiveCapacity: bigint = maxDepositRaw === null ? MAX_UINT256 : maxDepositRaw!;\n\n // ── Derive mode ────────────────────────────────────────────────────────────\n let mode: VaultMode;\n if (isPaused) {\n mode = \"paused\";\n } else if (effectiveCapacity === 0n) {\n mode = \"full\";\n } else if (!isHub) {\n mode = \"local\";\n } else if (oraclesEnabled) {\n mode = \"cross-chain-oracle\";\n } else {\n mode = \"cross-chain-async\";\n }\n\n // ── Recommended flows ──────────────────────────────────────────────────────\n let recommendedDepositFlow: VaultStatus[\"recommendedDepositFlow\"];\n let recommendedRedeemFlow: VaultStatus[\"recommendedRedeemFlow\"];\n\n if (mode === \"paused\" || mode === \"full\") {\n recommendedDepositFlow = \"none\";\n recommendedRedeemFlow = mode === \"paused\" ? \"none\" : \"redeemShares\";\n } else if (mode === \"cross-chain-async\") {\n recommendedDepositFlow = \"depositAsync\";\n recommendedRedeemFlow = \"redeemAsync\";\n } else {\n // local or cross-chain-oracle\n recommendedDepositFlow = \"depositSimple\";\n recommendedRedeemFlow = \"redeemShares\";\n }\n\n // ── Issues ─────────────────────────────────────────────────────────────────\n const issues: string[] = [];\n\n if (isPaused) {\n issues.push(\"Vault is paused — no deposits or redeems are possible.\");\n }\n if (effectiveCapacity === 0n && !isPaused) {\n issues.push(\n \"Deposit capacity is full — increase depositCapacity via setDepositCapacity().\"\n );\n }\n if (isHub && !oraclesEnabled && ccManager === ZeroAddress) {\n issues.push(\n \"CCManager not configured — async flows will revert. Call setCrossChainAccountingManager(address) as vault owner.\"\n );\n }\n if (isHub && !oraclesEnabled && escrow === ZeroAddress) {\n issues.push(\n \"Escrow not configured in registry — async flows will revert. Set the escrow via the MoreVaultsRegistry.\"\n );\n }\n if (depositAccessRestricted) {\n issues.push(\"Deposit access is restricted (whitelist or other access control). Only approved addresses can deposit.\");\n }\n\n // ── maxImmediateRedeemAssets ────────────────────────────────────────────────\n const maxImmediateRedeemAssets: bigint = isHub && !oraclesEnabled ? hubLiquidBalance : totalAssets;\n\n if (isHub) {\n if (hubLiquidBalance === 0n) {\n issues.push(\n `Hub has no liquid assets (hubLiquidBalance = 0). All redeems will be auto-refunded until the curator repatriates funds from spokes via executeBridging().`\n );\n } else if (totalAssets > 0n && hubLiquidBalance * 10n < totalAssets) {\n const pct = Number((hubLiquidBalance * 10000n) / totalAssets) / 100;\n issues.push(\n `Low hub liquidity: ${hubLiquidBalance} units liquid on hub (${pct.toFixed(1)}% of TVL). ` +\n `Redeems above ${hubLiquidBalance} underlying units will be auto-refunded. ` +\n `Curator must call executeBridging() to repatriate from spokes.`\n );\n }\n if (spokesDeployedBalance > 0n) {\n const total = totalAssets;\n issues.push(\n `${spokesDeployedBalance} units (~${((Number(spokesDeployedBalance) / Number(total || 1n)) * 100).toFixed(1)}% of TVL) ` +\n `are deployed on spoke chains earning yield. These are NOT immediately redeemable — ` +\n `they require a curator repatriation (executeBridging) before users can withdraw them.`\n );\n }\n }\n\n return {\n mode,\n recommendedDepositFlow,\n recommendedRedeemFlow,\n isHub,\n isPaused,\n oracleAccountingEnabled: oraclesEnabled,\n ccManager,\n escrow,\n withdrawalQueueEnabled,\n withdrawalTimelockSeconds: BigInt(withdrawalTimelockSeconds),\n remainingDepositCapacity: effectiveCapacity,\n depositAccessRestricted,\n underlying,\n totalAssets,\n totalSupply,\n decimals: decimalsNum,\n sharePrice,\n hubLiquidBalance,\n spokesDeployedBalance,\n maxImmediateRedeemAssets,\n issues,\n };\n}\n","import { Contract, AbiCoder, Signer, ZeroAddress } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { VAULT_ABI, BRIDGE_ABI, ERC20_ABI } from \"./abis\";\nimport {\n VaultAddresses,\n DepositResult,\n AsyncRequestResult,\n ActionType,\n} from \"./types\";\nimport { preflightAsync, preflightSync } from \"./preflight\";\nimport { EscrowNotConfiguredError, VaultPausedError, CapacityFullError } from \"./errors\";\nimport { validateWalletChain } from \"./chainValidation\";\nimport { getVaultStatus, quoteLzFee } from \"./utils\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n * Sends an approve TX only if current allowance is insufficient.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// D1 -- Simple deposit (1 TX, sync)\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit `assets` of the vault's underlying token and receive shares.\n *\n * TXs: 1 approve (if needed) + 1 deposit.\n *\n * @param signer - Wallet that holds the underlying tokens.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param assets - Amount of underlying tokens to deposit.\n * @param receiver - Address that will receive the minted shares.\n * @returns Shares minted and the transaction receipt.\n */\nexport async function depositSimple(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string\n): Promise<DepositResult> {\n const provider = signer.provider!;\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate vault is operational and accepting deposits\n await preflightSync(provider, addresses.vault);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n await ensureAllowance(signer, underlying, addresses.vault, assets);\n\n // Call the single-asset deposit overload: deposit(uint256, address)\n const tx = await vault[\"deposit(uint256,address)\"](assets, receiver);\n const receipt = await tx.wait();\n\n // Extract shares from the return value via Transfer event (from 0x0 = mint)\n let shares = 0n;\n for (const log of receipt.logs) {\n try {\n const parsed = vault.interface.parseLog({\n topics: log.topics as string[],\n data: log.data,\n });\n if (\n parsed &&\n parsed.name === \"Transfer\" &&\n parsed.args[0] === \"0x0000000000000000000000000000000000000000\"\n ) {\n shares = parsed.args[2];\n break;\n }\n } catch {\n // skip non-matching logs\n }\n }\n\n return { receipt, shares };\n}\n\n// ---------------------------------------------------------------------------\n// D2 -- Multi-asset deposit\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit multiple tokens in a single transaction.\n *\n * TXs: N approves (if needed) + 1 deposit.\n *\n * @param signer - Wallet holding the tokens.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param tokens - Array of token addresses to deposit.\n * @param amounts - Corresponding amounts for each token.\n * @param receiver - Address that will receive the minted shares.\n * @param minShares - Minimum acceptable shares (slippage protection).\n * @returns Shares minted and the transaction receipt.\n */\nexport async function depositMultiAsset(\n signer: Signer,\n addresses: VaultAddresses,\n tokens: string[],\n amounts: bigint[],\n receiver: string,\n minShares: bigint\n): Promise<DepositResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Approve each token\n for (let i = 0; i < tokens.length; i++) {\n await ensureAllowance(signer, tokens[i], addresses.vault, amounts[i]);\n }\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault[\n \"deposit(address[],uint256[],address,uint256)\"\n ](tokens, amounts, receiver, minShares);\n const receipt = await tx.wait();\n\n let shares = 0n;\n for (const log of receipt.logs) {\n try {\n const parsed = vault.interface.parseLog({\n topics: log.topics as string[],\n data: log.data,\n });\n if (parsed && parsed.name === \"Deposit\") {\n shares = parsed.args[4]; // 5th arg = shares\n break;\n }\n } catch {\n // skip\n }\n }\n\n return { receipt, shares };\n}\n\n// ---------------------------------------------------------------------------\n// D3 -- Cross-chain oracle ON (transparent, identical to D1)\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit when cross-chain oracle accounting is ON.\n * Behaves identically to a simple deposit because oracle provides\n * synchronous pricing.\n *\n * TXs: 1 approve (if needed) + 1 deposit.\n */\nexport const depositCrossChainOracleOn = depositSimple;\n\n// ---------------------------------------------------------------------------\n// D4 -- Cross-chain oracle OFF, async DEPOSIT\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain deposit request.\n *\n * CRITICAL: tokens are approved to the **escrow** address, not the vault.\n *\n * TXs: 1 approve to escrow (if needed) + 1 initVaultActionRequest.\n * After this call, a LayerZero message is sent; the caller must wait for\n * cross-chain fulfillment before shares are minted.\n *\n * @param signer - Wallet holding the underlying tokens.\n * @param addresses - Must include `vault` and `escrow`.\n * @param assets - Amount of underlying tokens to deposit.\n * @param receiver - Address that will receive shares on fulfillment.\n * @param lzFee - Native fee for LayerZero message (use `quoteLzFee`).\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function depositAsync(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n // CRITICAL: approve ESCROW, not vault\n await ensureAllowance(signer, underlying, escrow, assets);\n\n // Encode parameters only (no selector) — contracts use abi.decode on these bytes\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\"],\n [assets, receiver]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.DEPOSIT,\n actionCallData,\n 0,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.DEPOSIT,\n actionCallData,\n 0, // amountLimit = 0 for deposits (minAmountOut handled by cross-chain manager)\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n// ---------------------------------------------------------------------------\n// D5 -- Cross-chain oracle OFF, async MINT\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain mint request (exact shares).\n *\n * CRITICAL: tokens are approved to the **escrow** address, not the vault.\n *\n * TXs: 1 approve to escrow for maxAssets (if needed) + 1 initVaultActionRequest.\n *\n * @param signer - Wallet holding the underlying tokens.\n * @param addresses - Must include `vault` and `escrow`.\n * @param shares - Exact number of shares to mint.\n * @param maxAssets - Maximum underlying tokens to spend (slippage cap).\n * @param receiver - Address that will receive shares on fulfillment.\n * @param lzFee - Native fee for LayerZero message.\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function mintAsync(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n maxAssets: bigint,\n receiver: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n // CRITICAL: approve ESCROW for maxAssets\n await ensureAllowance(signer, underlying, escrow, maxAssets);\n\n // Encode parameters only (no selector) — contracts use abi.decode on these bytes\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\"],\n [shares, receiver]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.MINT,\n actionCallData,\n maxAssets,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.MINT,\n actionCallData,\n maxAssets,\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n/**\n * Smart deposit — auto-selects the correct flow based on vault configuration.\n *\n * Calls getVaultStatus internally to determine the vault mode, then dispatches\n * to the appropriate flow:\n * - local / cross-chain-oracle → depositSimple\n * - cross-chain-async → depositAsync (quotes LZ fee automatically)\n *\n * @param signer Wallet signer with account attached\n * @param provider Read-only provider for on-chain reads\n * @param addresses Vault address set (`escrow` required for async vaults)\n * @param assets Amount of underlying to deposit\n * @param receiver Address that will receive shares\n * @param extraOptions Optional LZ extra options (only used for async vaults)\n * @returns DepositResult or AsyncRequestResult depending on vault mode\n * @throws VaultPausedError if vault is paused\n * @throws CapacityFullError if vault is full\n */\nexport async function smartDeposit(\n signer: Signer,\n provider: Provider,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n extraOptions: string = \"0x\"\n): Promise<DepositResult | AsyncRequestResult> {\n const vault = addresses.vault;\n const status = await getVaultStatus(provider, vault);\n\n if (status.mode === \"paused\") {\n throw new VaultPausedError(vault);\n }\n if (status.mode === \"full\") {\n throw new CapacityFullError(vault);\n }\n\n if (status.recommendedDepositFlow === \"depositAsync\") {\n const lzFee = await quoteLzFee(provider, vault, extraOptions);\n return depositAsync(signer, addresses, assets, receiver, lzFee, extraOptions);\n }\n\n // local or cross-chain-oracle\n return depositSimple(signer, addresses, assets, receiver);\n}\n","import { Contract, AbiCoder, zeroPadValue, Signer, Provider } from \"ethers\";\nimport { ERC20_ABI, OFT_ABI, BRIDGE_ABI, LZ_ENDPOINT_ABI } from \"./abis\";\nimport type { ContractTransactionReceipt } from \"ethers\";\n\n/** LZ Endpoint V2 address — same on all EVM chains */\nconst LZ_ENDPOINT = \"0x1a44076050125825900e736c501f859c50fe728c\";\n\nconst EMPTY_HASH = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\nconst RECEIVED_HASH = \"0x0000000000000000000000000000000000000000000000000000000000000001\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// D6 / D7 — Spoke → Hub, OFT Compose deposit\n// ---------------------------------------------------------------------------\n\n/**\n * D6 / D7 — Deposit from a spoke chain to the hub vault via OFT Compose.\n *\n * Bridges tokens from the spoke chain to the hub via LayerZero OFT, attaching a\n * composeMsg that instructs the hub-side MoreVaultsComposer to deposit into the vault.\n * Shares are delivered on the hub chain (local safeTransfer).\n *\n * - **D6 (oracle ON)**: composer calls `_depositAndSend` — shares arrive immediately on hub.\n * - **D7 (oracle OFF)**: composer calls `_initDeposit` — requires an additional LZ Read round-trip.\n *\n * TXs: 1 approve (if needed) + 1 OFT.send().\n *\n * @param signer - Wallet on the spoke chain.\n * @param spokeOFT - OFT/OFTAdapter address on the spoke chain.\n * @param composer - MoreVaultsComposer address on the hub chain.\n * @param hubEid - LayerZero EID for the hub chain.\n * @param spokeEid - LayerZero EID for the spoke chain — where shares are sent back.\n * @param amount - Amount of underlying tokens to bridge and deposit.\n * @param receiver - Address that will receive shares on the hub chain.\n * @param lzFee - Native fee for the OFT.send() call.\n * @param minMsgValue - Minimum msg.value the hub composer must receive (default 0).\n * @param minSharesOut - Minimum shares to receive after deposit (default 0).\n * @param minAmountLD - Minimum tokens received on hub after bridge (default: amount).\n * @param extraOptions - LZ extra options bytes (default '0x').\n * @returns Transaction receipt.\n */\nexport async function depositFromSpoke(\n signer: Signer,\n spokeOFT: string,\n composer: string,\n hubEid: number,\n spokeEid: number,\n amount: bigint,\n receiver: string,\n lzFee: bigint,\n minMsgValue: bigint = 0n,\n minSharesOut: bigint = 0n,\n minAmountLD?: bigint,\n extraOptions: string = \"0x\",\n): Promise<{ receipt: ContractTransactionReceipt }> {\n await ensureAllowance(signer, spokeOFT, spokeOFT, amount);\n\n const oft = new Contract(spokeOFT, OFT_ABI, signer);\n const refundAddress = await signer.getAddress();\n\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const composerBytes32 = zeroPadValue(composer, 32);\n\n // hopSendParam: dstEid = spokeEid → shares sent back to user on spoke via SHARE_OFT\n // Requires SHARE_OFT peers + enforcedOptions configured on both chains.\n // For Stargate OFTs: compose stays pending (msg.value=0), user retries via executeCompose.\n const hopSendParam = {\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 0n,\n minAmountLD: minSharesOut,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const coder = AbiCoder.defaultAbiCoder();\n const composeMsg = coder.encode(\n [\n \"tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd)\",\n \"uint256\",\n ],\n [hopSendParam, minMsgValue],\n );\n\n const sendParam = {\n dstEid: hubEid,\n to: composerBytes32,\n amountLD: amount,\n minAmountLD: minAmountLD ?? amount,\n extraOptions,\n composeMsg,\n oftCmd: \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// D7 -- Spoke -> Hub OFT Compose (oracle OFF, async)\n// ---------------------------------------------------------------------------\n\n/**\n * Alias: D7 — Spoke to hub deposit when oracle is OFF (async resolution).\n * Same interface as D6; the difference is handled server-side by the composer contract.\n */\nexport const depositFromSpokeAsync = depositFromSpoke;\n\n// ---------------------------------------------------------------------------\n// Fee quote helper\n// ---------------------------------------------------------------------------\n\n/**\n * Quote the LayerZero fee required for depositFromSpoke.\n *\n * @param provider Read-only provider on the SPOKE chain\n * @param spokeOFT OFT contract address on spoke chain\n * @param composer MoreVaultsComposer address on the hub chain\n * @param hubEid LayerZero EID for the hub chain\n * @param amount Amount of tokens to bridge\n * @param receiver Address that will receive vault shares\n * @param minMsgValue Same value you plan to pass to depositFromSpoke (default 0n)\n * @param minSharesOut Same value you plan to pass to depositFromSpoke (default 0n)\n * @param minAmountLD Minimum tokens on hub after bridge (default: amount)\n * @param extraOptions LZ extra options (default 0x)\n * @returns Native fee in wei\n */\nexport async function quoteDepositFromSpokeFee(\n provider: Provider,\n spokeOFT: string,\n composer: string,\n hubEid: number,\n spokeEid: number,\n amount: bigint,\n receiver: string,\n minMsgValue: bigint = 0n,\n minSharesOut: bigint = 0n,\n minAmountLD?: bigint,\n extraOptions: string = \"0x\"\n): Promise<bigint> {\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const composerBytes32 = zeroPadValue(composer, 32);\n\n // hopSendParam with dstEid=spokeEid → shares go back to spoke via SHARE_OFT\n const hopSendParam = {\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 0n,\n minAmountLD: minSharesOut,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const coder = AbiCoder.defaultAbiCoder();\n const composeMsgBytes = coder.encode(\n [\"tuple(uint32,bytes32,uint256,uint256,bytes,bytes,bytes)\", \"uint256\"],\n [\n [\n hopSendParam.dstEid,\n hopSendParam.to,\n hopSendParam.amountLD,\n hopSendParam.minAmountLD,\n hopSendParam.extraOptions,\n hopSendParam.composeMsg,\n hopSendParam.oftCmd,\n ],\n minMsgValue,\n ]\n );\n\n const sendParam = {\n dstEid: hubEid,\n to: composerBytes32,\n amountLD: amount,\n minAmountLD: minAmountLD ?? amount,\n extraOptions,\n composeMsg: composeMsgBytes,\n oftCmd: \"0x\",\n };\n\n const oft = new Contract(spokeOFT, OFT_ABI, provider);\n const fee = await oft.quoteSend(sendParam, false);\n return fee.nativeFee as bigint;\n}\n\n// ---------------------------------------------------------------------------\n// Stargate 2-TX compose helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Quote the ETH needed to execute a pending compose on the hub chain.\n *\n * For D7 (oracle OFF) vaults, the composer needs ETH to cover:\n * 1. `readFee` for `vault.initVaultActionRequest`\n * 2. `shareSendFee` for `SHARE_OFT.send()` to deliver shares to the spoke chain\n *\n * @param provider Read-only provider on the HUB chain\n * @param vault Vault address on the hub\n * @param spokeEid Destination EID for share delivery (optional — improves accuracy)\n * @param receiver Receiver address on the spoke chain (optional — improves accuracy)\n * @returns ETH amount in wei to send with executeCompose\n */\nexport async function quoteComposeFee(\n provider: Provider,\n vault: string,\n spokeEid?: number,\n receiver?: string,\n): Promise<bigint> {\n try {\n const vaultContract = new Contract(vault, BRIDGE_ABI, provider);\n const readFee: bigint = await vaultContract.quoteAccountingFee(\"0x\");\n\n // If spokeEid provided, also quote the SHARE_OFT send fee\n let shareSendFee = 0n;\n if (spokeEid && receiver) {\n try {\n const COMPOSER_ABI = [\"function SHARE_OFT() view returns (address)\"];\n const FACTORY_ABI = [\"function vaultComposer(address _vault) view returns (address)\"];\n const factory = new Contract(\"0x7bDB8B17604b03125eFAED33cA0c55FBf856BB0C\", FACTORY_ABI, provider);\n const composerAddr: string = await factory.vaultComposer(vault);\n const composer = new Contract(composerAddr, COMPOSER_ABI, provider);\n const shareOftAddr: string = await composer.SHARE_OFT();\n const shareOft = new Contract(shareOftAddr, OFT_ABI, provider);\n\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const fee = await shareOft.quoteSend({\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 1_000_000n,\n minAmountLD: 0n,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n }, false);\n shareSendFee = fee.nativeFee as bigint;\n } catch { /* fallback to readFee only */ }\n }\n\n return (readFee + shareSendFee) * 110n / 100n; // 10% buffer\n } catch {\n return 500_000_000_000_000n; // 0.0005 ETH fallback\n }\n}\n\n/**\n * Execute a pending LZ compose on the hub chain (Stargate 2-TX flow, step 2).\n *\n * Calls `endpoint.lzCompose{value: fee}(from, to, guid, index, message, '0x')`.\n *\n * @param signer Wallet on the HUB chain\n * @param from Stargate pool address on hub (from ComposeSent event)\n * @param to MoreVaultsComposer address on hub\n * @param guid LayerZero GUID from the original OFT.send()\n * @param message Full compose message bytes (from ComposeSent event)\n * @param fee ETH to send (from quoteComposeFee)\n * @param index Compose index (default 0)\n * @returns Transaction receipt\n */\nexport async function executeCompose(\n signer: Signer,\n from: string,\n to: string,\n guid: string,\n message: string,\n fee: bigint,\n index: number = 0,\n): Promise<{ receipt: ContractTransactionReceipt }> {\n const endpoint = new Contract(LZ_ENDPOINT, LZ_ENDPOINT_ABI, signer);\n\n // Verify compose is still pending\n const hash: string = await endpoint.composeQueue(from, to, guid, index);\n if (hash === EMPTY_HASH) {\n throw new Error(\"Compose not found in queue (hash = 0). Never sent or wrong parameters.\");\n }\n if (hash === RECEIVED_HASH) {\n throw new Error(\"Compose already delivered — no action needed.\");\n }\n\n const tx = await endpoint.lzCompose(from, to, guid, index, message, \"0x\", {\n value: fee,\n gasLimit: 5_000_000n,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n","import { Contract, AbiCoder, zeroPadValue, Signer, Provider, ZeroAddress } from \"ethers\";\nimport {\n VAULT_ABI,\n BRIDGE_ABI,\n ERC20_ABI,\n OFT_ABI,\n} from \"./abis\";\nimport {\n VaultAddresses,\n RedeemResult,\n AsyncRequestResult,\n ActionType,\n} from \"./types\";\nimport type { ContractTransactionReceipt } from \"ethers\";\nimport { preflightAsync, preflightRedeemLiquidity } from \"./preflight\";\nimport { EscrowNotConfiguredError } from \"./errors\";\nimport { validateWalletChain } from \"./chainValidation\";\nimport { getVaultStatus, quoteLzFee } from \"./utils\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// R1 -- Simple redeem\n// ---------------------------------------------------------------------------\n\n/**\n * Redeem `shares` for underlying assets.\n *\n * TXs: 1 redeem.\n * Pre-condition: if withdrawal queue is enabled, `requestRedeem` must have\n * been called and the timelock must have elapsed.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param shares - Number of shares to redeem.\n * @param receiver - Address that will receive the underlying assets.\n * @param owner - Address that owns the shares.\n * @returns Assets received and the transaction receipt.\n */\nexport async function redeemShares(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string\n): Promise<RedeemResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n\n // Static call to get the return value (assets) before broadcasting\n const assets: bigint = await vault.redeem.staticCall(shares, receiver, owner);\n\n const tx = await vault.redeem(shares, receiver, owner);\n const receipt = await tx.wait();\n\n return { receipt, assets };\n}\n\n// ---------------------------------------------------------------------------\n// R2 -- Simple withdraw\n// ---------------------------------------------------------------------------\n\n/**\n * Withdraw exact `assets` amount of underlying tokens by burning shares.\n *\n * TXs: 1 withdraw.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param assets - Exact amount of underlying tokens to withdraw.\n * @param receiver - Address that will receive the tokens.\n * @param owner - Address that owns the shares.\n * @returns Assets received and the transaction receipt.\n */\nexport async function withdrawAssets(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n owner: string\n): Promise<RedeemResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault.withdraw(assets, receiver, owner);\n const receipt = await tx.wait();\n\n return { receipt, assets };\n}\n\n// ---------------------------------------------------------------------------\n// R3 -- Queue redeem, no timelock (2 TXs)\n// ---------------------------------------------------------------------------\n\n/**\n * Submit a withdrawal queue request for `shares`.\n *\n * TXs: 1 requestRedeem.\n * After this call and once any timelock elapses, call `redeemShares()` to\n * complete the withdrawal.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param shares - Number of shares to queue for redemption.\n * @param owner - Address on whose behalf to request.\n * @returns Transaction receipt.\n */\nexport async function requestRedeem(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n owner: string\n): Promise<{ receipt: ContractTransactionReceipt }> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault.requestRedeem(shares, owner);\n const receipt = await tx.wait();\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// R4 -- Queue redeem with timelock (helper to check status)\n// ---------------------------------------------------------------------------\n\n/**\n * Get the current withdrawal request for an owner.\n * Returns null if no pending request exists.\n *\n * @param provider - JSON-RPC provider.\n * @param vault - Vault (diamond) address.\n * @param owner - Address of the shares owner.\n * @returns The request details or null.\n */\nexport async function getWithdrawalRequest(\n provider: Provider,\n vault: string,\n owner: string\n): Promise<{ shares: bigint; timelockEndsAt: bigint } | null> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const [shares, timelockEndsAt]: [bigint, bigint] =\n await vaultContract.getWithdrawalRequest(owner);\n\n if (shares === 0n) {\n return null;\n }\n\n return { shares, timelockEndsAt };\n}\n\n// ---------------------------------------------------------------------------\n// R5 -- Cross-chain oracle OFF, async redeem\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain redeem request.\n *\n * CRITICAL: shares are approved to the **escrow** address (vault share token).\n * amountLimit MUST be 0 for redeems.\n *\n * TXs: 1 approve to escrow for shares (if needed) + 1 initVaultActionRequest.\n * Wait: LayerZero cross-chain fulfillment.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Must include `vault` and `escrow`.\n * @param shares - Number of shares to redeem.\n * @param receiver - Address that will receive the underlying assets.\n * @param owner - Address that owns the shares.\n * @param lzFee - Native fee for LayerZero message.\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function redeemAsync(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n // Pre-flight: check hub has enough liquid assets — avoids wasting LZ fee on a guaranteed refund\n await preflightRedeemLiquidity(provider, addresses.vault, shares);\n\n // CRITICAL: approve ESCROW for shares (the vault token itself)\n await ensureAllowance(signer, addresses.vault, escrow, shares);\n\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\", \"address\"],\n [shares, receiver, owner]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.REDEEM,\n actionCallData,\n 0,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.REDEEM,\n actionCallData,\n 0, // amountLimit MUST be 0 for redeems\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n// ---------------------------------------------------------------------------\n// R6 -- Spoke -> Hub redeem (step 1: bridge shares to hub)\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge shares from a spoke chain to the hub chain (step 1 of 2).\n *\n * After the shares arrive on the hub chain, call `redeemShares()` on the\n * hub to complete the redemption.\n *\n * TXs: 1 approve (if needed) + 1 OFT.send().\n * Wait: LayerZero delivery (typically 1-5 minutes).\n *\n * @param signer - Wallet on the spoke chain holding shares.\n * @param shareOFT - OFTAdapter address for the share token on spoke.\n * @param hubChainEid - LayerZero endpoint ID for the hub chain (e.g. 30336 for Flow EVM).\n * @param shares - Number of shares to bridge.\n * @param receiver - Address on hub chain that will receive the shares.\n * @param lzFee - Native fee for LayerZero message.\n * @returns Transaction receipt.\n */\nexport async function bridgeSharesToHub(\n signer: Signer,\n shareOFT: string,\n hubChainEid: number,\n shares: bigint,\n receiver: string,\n lzFee: bigint\n): Promise<{ receipt: ContractTransactionReceipt }> {\n await ensureAllowance(signer, shareOFT, shareOFT, shares);\n\n const oft = new Contract(shareOFT, OFT_ABI, signer);\n const refundAddress = await signer.getAddress();\n const toBytes32 = zeroPadValue(receiver, 32);\n\n const sendParam = {\n dstEid: hubChainEid,\n to: toBytes32,\n amountLD: shares,\n minAmountLD: shares, // no slippage on share bridging\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// Smart redeem -- auto-detect vault type\n// ---------------------------------------------------------------------------\n\n/**\n * Smart redeem — auto-selects the correct flow based on vault configuration.\n *\n * Detects the vault mode and dispatches to:\n * - Sync vaults (local / cross-chain-oracle): `redeemShares`\n * - Async vaults (cross-chain, oracle OFF): `redeemAsync` (quotes LZ fee automatically)\n *\n * @param signer Wallet signer with account attached\n * @param addresses Vault address set (`escrow` required for async vaults)\n * @param shares Amount of shares to redeem\n * @param receiver Address that will receive the underlying assets\n * @param owner Owner of the shares being redeemed\n * @param extraOptions Optional LZ extra options (only used for async vaults)\n * @returns RedeemResult or AsyncRequestResult depending on vault mode\n */\nexport async function smartRedeem(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string,\n extraOptions: string = \"0x\"\n): Promise<RedeemResult | AsyncRequestResult> {\n const provider = signer.provider!;\n const vault = addresses.vault;\n const status = await getVaultStatus(provider, vault);\n\n if (status.mode === \"paused\") {\n throw new Error(`[MoreVaults] Vault ${vault} is paused. Cannot redeem.`);\n }\n\n if (status.recommendedDepositFlow === \"depositAsync\") {\n // Async vault — use redeemAsync\n const lzFee = await quoteLzFee(provider, vault, extraOptions);\n return redeemAsync(signer, addresses, shares, receiver, owner, lzFee, extraOptions);\n }\n\n // Sync vault — direct redeem\n return redeemShares(signer, addresses, shares, receiver, owner);\n}\n\n// ---------------------------------------------------------------------------\n// R7 -- Bridge assets from hub back to spoke\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge underlying assets from hub back to spoke chain via OFT.\n *\n * Step 3 of the full spoke redeem flow:\n * 1. bridgeSharesToHub() — shares spoke->hub\n * 2. smartRedeem() — redeem on hub\n * 3. bridgeAssetsToSpoke() — assets hub->spoke\n *\n * @param signer Wallet signer on the HUB chain\n * @param assetOFT OFT address for the underlying asset on hub\n * @param spokeChainEid LayerZero EID for the spoke (destination) chain\n * @param amount Amount of underlying assets to bridge\n * @param receiver Receiver address on the spoke chain\n * @param lzFee OFT send fee (quote via OFT.quoteSend)\n * @param isStargate Whether this is a Stargate OFT (uses TAXI mode)\n * @returns Transaction receipt\n */\nexport async function bridgeAssetsToSpoke(\n signer: Signer,\n assetOFT: string,\n spokeChainEid: number,\n amount: bigint,\n receiver: string,\n lzFee: bigint,\n isStargate: boolean = true\n): Promise<{ receipt: ContractTransactionReceipt }> {\n const oft = new Contract(assetOFT, OFT_ABI, signer);\n\n // Read underlying token and approve\n const token: string = await oft.token();\n if (token.toLowerCase() !== assetOFT.toLowerCase()) {\n await ensureAllowance(signer, token, assetOFT, amount);\n } else {\n await ensureAllowance(signer, assetOFT, assetOFT, amount);\n }\n\n const refundAddress = await signer.getAddress();\n const toBytes32 = zeroPadValue(receiver, 32);\n\n const sendParam = {\n dstEid: spokeChainEid,\n to: toBytes32,\n amountLD: amount,\n minAmountLD: amount * 99n / 100n, // 1% slippage for Stargate\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: isStargate ? \"0x01\" : \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n","/**\n * User-facing helper functions for the MoreVaults ethers.js v6 SDK.\n *\n * All functions use Provider (read-only). None send transactions.\n */\n\nimport { Contract, Interface } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { BRIDGE_ABI, CONFIG_ABI, ERC20_ABI, VAULT_ABI, METADATA_ABI } from \"./abis\";\nimport type { CrossChainRequestInfo } from \"./types\";\nimport { getVaultStatus } from \"./utils\";\nimport type { VaultStatus } from \"./utils\";\n\n// Multicall3 — deployed at the same address on every EVM chain\nconst MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\nconst MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface UserPosition {\n /** Vault share balance */\n shares: bigint;\n /** convertToAssets(shares) — what they'd get if they redeemed now */\n estimatedAssets: bigint;\n /** Price of 1 full share in underlying (convertToAssets(10n ** decimals)) */\n sharePrice: bigint;\n /** Vault decimals (for display) */\n decimals: number;\n pendingWithdrawal: {\n shares: bigint;\n timelockEndsAt: bigint;\n /** block.timestamp >= timelockEndsAt (or timelockEndsAt === 0n) */\n canRedeemNow: boolean;\n } | null; // null if no pending withdrawal request\n}\n\n/**\n * Read the user's current position in the vault.\n *\n * @param provider Read-only provider for reads\n * @param vault Vault address (diamond proxy)\n * @param user User wallet address\n * @returns Full user position snapshot\n */\nexport async function getUserPosition(\n provider: Provider,\n vault: string,\n user: string\n): Promise<UserPosition> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // First batch: balance, decimals, withdrawal request — via Multicall3\n const b1Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"getWithdrawalRequest\", [user]) },\n ];\n\n const [b1Raw, block] = await Promise.all([\n mc.aggregate3.staticCall(b1Calls) as Promise<{ success: boolean; returnData: string }[]>,\n provider.getBlock(\"latest\"),\n ]);\n\n const shares = vaultIface.decodeFunctionResult(\"balanceOf\", b1Raw[0].returnData)[0] as bigint;\n const decimalsRaw = decimalsIface.decodeFunctionResult(\"decimals\", b1Raw[1].returnData)[0];\n const decimals = Number(decimalsRaw);\n const withdrawalResult = vaultIface.decodeFunctionResult(\"getWithdrawalRequest\", b1Raw[2].returnData);\n const withdrawalRequest: [bigint, bigint] = [withdrawalResult[0] as bigint, withdrawalResult[1] as bigint];\n\n const [withdrawShares, timelockEndsAt] = withdrawalRequest;\n\n // Second batch: convertToAssets calls (need shares and decimals from first batch)\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const oneShare = 10n ** BigInt(decimals);\n const [estimatedAssets, sharePrice] = await Promise.all([\n shares === 0n\n ? Promise.resolve(0n)\n : (vaultContract.convertToAssets(shares) as Promise<bigint>),\n vaultContract.convertToAssets(oneShare) as Promise<bigint>,\n ]);\n\n const currentTimestamp = BigInt(block!.timestamp);\n\n const pendingWithdrawal =\n withdrawShares === 0n\n ? null\n : {\n shares: withdrawShares,\n timelockEndsAt,\n canRedeemNow:\n timelockEndsAt === 0n || currentTimestamp >= timelockEndsAt,\n };\n\n return {\n shares,\n estimatedAssets,\n sharePrice,\n decimals,\n pendingWithdrawal,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Preview how many shares a given asset amount would mint.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param assets Amount of underlying tokens to deposit\n * @returns Estimated shares to be minted\n */\nexport async function previewDeposit(\n provider: Provider,\n vault: string,\n assets: bigint\n): Promise<bigint> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n return vaultContract.previewDeposit(assets) as Promise<bigint>;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Preview how many underlying assets a given share amount would redeem.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param shares Amount of vault shares to redeem\n * @returns Estimated assets to be returned\n */\nexport async function previewRedeem(\n provider: Provider,\n vault: string,\n shares: bigint\n): Promise<bigint> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n return vaultContract.previewRedeem(shares) as Promise<bigint>;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type DepositBlockReason =\n | \"paused\"\n | \"capacity-full\"\n | \"not-whitelisted\"\n | \"ok\";\n\nexport interface DepositEligibility {\n allowed: boolean;\n reason: DepositBlockReason;\n}\n\n/**\n * Check whether a user is eligible to deposit into the vault right now.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Eligibility result with reason\n */\nexport async function canDeposit(\n provider: Provider,\n vault: string,\n user: string\n): Promise<DepositEligibility> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n\n const isPaused = await (config.paused() as Promise<boolean>);\n\n if (isPaused) {\n return { allowed: false, reason: \"paused\" };\n }\n\n // maxDeposit(user) can REVERT on vaults with whitelist/ACL\n let maxDepositAmount: bigint;\n try {\n maxDepositAmount = await (config.maxDeposit(user) as Promise<bigint>);\n } catch {\n // Revert means the vault has whitelist/ACL and this user is not approved\n return { allowed: false, reason: \"not-whitelisted\" };\n }\n\n if (maxDepositAmount === 0n) {\n return { allowed: false, reason: \"capacity-full\" };\n }\n return { allowed: true, reason: \"ok\" };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface VaultMetadata {\n name: string;\n symbol: string;\n decimals: number;\n underlying: string;\n underlyingSymbol: string;\n underlyingDecimals: number;\n}\n\n/**\n * Read display metadata for a vault and its underlying token.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns Vault and underlying token metadata\n */\nexport async function getVaultMetadata(\n provider: Provider,\n vault: string\n): Promise<VaultMetadata> {\n const MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\n const MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n ] as const;\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const metaIface = new Interface(METADATA_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n\n // Batch 1: name, symbol, decimals, asset — 1 eth_call via Multicall3\n const b1Calls = [\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"name\") },\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const name = metaIface.decodeFunctionResult(\"name\", b1[0].returnData)[0] as string;\n const symbol = metaIface.decodeFunctionResult(\"symbol\", b1[1].returnData)[0] as string;\n const decimals = Number(metaIface.decodeFunctionResult(\"decimals\", b1[2].returnData)[0]);\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[3].returnData)[0] as string;\n\n // Batch 2: underlying symbol + decimals — 1 eth_call via Multicall3\n const b2Calls = [\n { target: underlying, allowFailure: false, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: underlying, allowFailure: false, callData: metaIface.encodeFunctionData(\"decimals\") },\n ];\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const underlyingSymbol = metaIface.decodeFunctionResult(\"symbol\", b2[0].returnData)[0] as string;\n const underlyingDecimals = Number(metaIface.decodeFunctionResult(\"decimals\", b2[1].returnData)[0]);\n\n return {\n name,\n symbol,\n decimals,\n underlying,\n underlyingSymbol,\n underlyingDecimals,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type AsyncRequestStatus =\n | \"pending\"\n | \"ready-to-execute\"\n | \"completed\"\n | \"refunded\";\n\nexport interface AsyncRequestStatusInfo {\n status: AsyncRequestStatus;\n /** Human-readable description */\n label: string;\n /** Shares minted or assets returned (0 if still pending) */\n result: bigint;\n}\n\n/**\n * Get the human-readable status of an async cross-chain request.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param guid Request GUID returned by depositAsync / mintAsync / redeemAsync\n * @returns Status info with label and result\n */\nexport async function getAsyncRequestStatusLabel(\n provider: Provider,\n vault: string,\n guid: string\n): Promise<AsyncRequestStatusInfo> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [info, finalizationResult]: [CrossChainRequestInfo, bigint] =\n await Promise.all([\n bridge.getRequestInfo(guid) as Promise<CrossChainRequestInfo>,\n bridge.getFinalizationResult(guid) as Promise<bigint>,\n ]);\n\n if (info.refunded) {\n return {\n status: \"refunded\",\n label: \"Request refunded — tokens returned to initiator\",\n result: 0n,\n };\n }\n if (info.finalized) {\n return {\n status: \"completed\",\n label: \"Completed\",\n result: finalizationResult,\n };\n }\n if (info.fulfilled) {\n return {\n status: \"ready-to-execute\",\n label: \"Oracle responded — ready to execute\",\n result: 0n,\n };\n }\n return {\n status: \"pending\",\n label: \"Waiting for cross-chain oracle response...\",\n result: 0n,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface UserBalances {\n /** Vault shares the user holds */\n shareBalance: bigint;\n /** Underlying token balance in wallet (for deposit input) */\n underlyingBalance: bigint;\n /** convertToAssets(shareBalance) — vault position value */\n estimatedAssets: bigint;\n}\n\n/**\n * Read the user's token balances relevant to a vault.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Share balance, underlying wallet balance, and estimated assets\n */\nexport async function getUserBalances(\n provider: Provider,\n vault: string,\n user: string\n): Promise<UserBalances> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // Batch 1: shareBalance, decimals, underlying address\n const b1Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const shareBalance = vaultIface.decodeFunctionResult(\"balanceOf\", b1[0].returnData)[0] as bigint;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[2].returnData)[0] as string;\n\n // Batch 2: underlying wallet balance + estimated assets (skip convertToAssets if no shares)\n const [underlyingBalance, estimatedAssets] = await Promise.all([\n (new Contract(underlying, ERC20_ABI, provider).balanceOf(user) as Promise<bigint>),\n shareBalance === 0n\n ? Promise.resolve(0n)\n : (new Contract(vault, VAULT_ABI, provider).convertToAssets(shareBalance) as Promise<bigint>),\n ]);\n\n return {\n shareBalance,\n underlyingBalance,\n estimatedAssets,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MaxWithdrawable {\n /** How many shares can be redeemed right now */\n shares: bigint;\n /** How many underlying assets that corresponds to */\n assets: bigint;\n}\n\n/**\n * Calculate the maximum amount a user can withdraw from a vault right now.\n *\n * For hub vaults without oracle accounting, this is limited by hub liquidity.\n * For local and oracle vaults, all assets are immediately redeemable.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Maximum withdrawable shares and assets\n */\nexport async function getMaxWithdrawable(\n provider: Provider,\n vault: string,\n user: string\n): Promise<MaxWithdrawable> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const configIface = new Interface(CONFIG_ABI as unknown as string[]);\n const bridgeIface = new Interface(BRIDGE_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n\n // Batch 1: isHub, oraclesCrossChainAccounting, user share balance, underlying\n const b1Calls = [\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"isHub\") },\n { target: vault, allowFailure: false, callData: bridgeIface.encodeFunctionData(\"oraclesCrossChainAccounting\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const isHub = configIface.decodeFunctionResult(\"isHub\", b1[0].returnData)[0] as boolean;\n const oraclesEnabled = bridgeIface.decodeFunctionResult(\"oraclesCrossChainAccounting\", b1[1].returnData)[0] as boolean;\n const userShares = vaultIface.decodeFunctionResult(\"balanceOf\", b1[2].returnData)[0] as bigint;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[3].returnData)[0] as string;\n\n if (userShares === 0n) {\n return { shares: 0n, assets: 0n };\n }\n\n // Batch 2: estimated assets + hub liquid balance\n const b2Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"convertToAssets\", [userShares]) },\n { target: underlying, allowFailure: false, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [vault]) },\n ];\n\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const estimatedAssets = vaultIface.decodeFunctionResult(\"convertToAssets\", b2[0].returnData)[0] as bigint;\n const hubLiquidBalance = erc20Iface.decodeFunctionResult(\"balanceOf\", b2[1].returnData)[0] as bigint;\n\n let maxAssets: bigint;\n if (isHub && !oraclesEnabled) {\n maxAssets = estimatedAssets < hubLiquidBalance ? estimatedAssets : hubLiquidBalance;\n } else {\n maxAssets = estimatedAssets;\n }\n\n let maxShares: bigint;\n if (maxAssets < estimatedAssets) {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n maxShares = await (vaultContract.convertToShares(maxAssets) as Promise<bigint>);\n } else {\n maxShares = userShares;\n }\n\n return {\n shares: maxShares,\n assets: maxAssets,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type VaultSummary = VaultStatus & VaultMetadata;\n\n/**\n * Get a combined snapshot of vault status and metadata in one call.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns Merged VaultStatus and VaultMetadata\n */\nexport async function getVaultSummary(\n provider: Provider,\n vault: string\n): Promise<VaultSummary> {\n const [status, metadata] = await Promise.all([\n getVaultStatus(provider, vault),\n getVaultMetadata(provider, vault),\n ]);\n return { ...status, ...metadata };\n}\n","import type { Signer } from 'ethers'\n\n/**\n * Cast an ethers Signer (e.g. from wagmi's useEthersSigner adapter) to\n * the SDK's expected type. Use this to avoid `as any` casts:\n * ```ts\n * import { useEthersSigner } from './wagmi-ethers-adapter'\n * import { asSdkSigner } from '@oydual31/more-vaults-sdk/ethers'\n * const signer = asSdkSigner(useEthersSigner())\n * ```\n * This function validates the signer is non-null and applies a documented\n * cast instead of an opaque `as any`.\n */\nexport function asSdkSigner(signer: unknown): Signer {\n if (!signer) throw new Error('[MoreVaults] No signer available. Make sure the wallet is connected and wagmi is configured correctly.')\n return signer as Signer\n}\n"]}
1
+ {"version":3,"sources":["../../src/ethers/chains.ts","../../src/ethers/types.ts","../../src/ethers/abis.ts","../../src/ethers/errors.ts","../../src/ethers/utils.ts","../../src/ethers/crossChainFlows.ts","../../src/ethers/preflight.ts","../../src/ethers/chainValidation.ts","../../src/ethers/depositFlows.ts","../../src/ethers/topology.ts","../../src/ethers/redeemFlows.ts","../../src/ethers/userHelpers.ts","../../src/ethers/curatorStatus.ts","../../src/ethers/curatorMulticall.ts","../../src/ethers/curatorSwaps.ts","../../src/ethers/distribution.ts","../../src/ethers/spokeRoutes.ts","../../src/ethers/wagmiCompat.ts"],"names":["JsonRpcProvider","Contract","Interface","ZeroAddress","ensureAllowance","zeroPadValue","AbiCoder","FACTORY_ABI","localChainId","MULTICALL3_ADDRESS","MULTICALL3_ABI"],"mappings":"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","file":"index.cjs","sourcesContent":["import { JsonRpcProvider } from \"ethers\";\nimport type { Provider } from \"ethers\";\n\n/** EVM Chain IDs for chains supported by MoreVaults */\nexport const CHAIN_IDS = {\n flowEVMMainnet: 747,\n flowEVMTestnet: 545,\n arbitrum: 42161,\n base: 8453,\n ethereum: 1,\n optimism: 10,\n sonic: 146,\n bsc: 56,\n} as const;\n\n/**\n * LayerZero Endpoint IDs (EID) for chains supported by MoreVaults.\n * Verified on-chain via MoreVaults OmniFactory.localEid() on each chain.\n * - flowMainnet: 30336 (0x7680) — confirmed from factory + LZ endpoint on Flow EVM mainnet\n */\nexport const LZ_EIDS = {\n flowMainnet: 30336,\n flowTestnet: 30333,\n arbitrum: 30110,\n base: 30184,\n ethereum: 30101,\n optimism: 30111,\n sonic: 30332,\n bsc: 30102,\n} as const;\n\n/** LayerZero EID → EVM Chain ID */\nexport const EID_TO_CHAIN_ID: Record<number, number> = {\n [LZ_EIDS.flowMainnet]: CHAIN_IDS.flowEVMMainnet,\n [LZ_EIDS.flowTestnet]: CHAIN_IDS.flowEVMTestnet,\n [LZ_EIDS.arbitrum]: CHAIN_IDS.arbitrum,\n [LZ_EIDS.base]: CHAIN_IDS.base,\n [LZ_EIDS.ethereum]: CHAIN_IDS.ethereum,\n [LZ_EIDS.optimism]: CHAIN_IDS.optimism,\n [LZ_EIDS.sonic]: CHAIN_IDS.sonic,\n [LZ_EIDS.bsc]: CHAIN_IDS.bsc,\n};\n\n/** EVM Chain ID → LayerZero EID */\nexport const CHAIN_ID_TO_EID: Record<number, number> = {\n [CHAIN_IDS.flowEVMMainnet]: LZ_EIDS.flowMainnet,\n [CHAIN_IDS.flowEVMTestnet]: LZ_EIDS.flowTestnet,\n [CHAIN_IDS.arbitrum]: LZ_EIDS.arbitrum,\n [CHAIN_IDS.base]: LZ_EIDS.base,\n [CHAIN_IDS.ethereum]: LZ_EIDS.ethereum,\n [CHAIN_IDS.optimism]: LZ_EIDS.optimism,\n [CHAIN_IDS.sonic]: LZ_EIDS.sonic,\n [CHAIN_IDS.bsc]: LZ_EIDS.bsc,\n};\n\n/**\n * LayerZero v2 OFT route config per asset symbol.\n *\n * Each entry maps chainId → { oft, token } where:\n * - `oft` = OFT contract to call send() on (pass as `spokeOFT` to depositFromSpoke)\n * - `token` = underlying ERC-20 the user approves before bridging\n * (zero address = native ETH, no approval needed)\n *\n * All routes verified on-chain via quoteSend() or peers(). Issuers vary per asset.\n */\nexport const OFT_ROUTES = {\n /**\n * stgUSDC — USDC bridged via Stargate v2.\n * Underlying on Eth/Arb/Base/Op: native USDC. On Flow: stgUSDC (Stargate's wrapped USDC).\n */\n stgUSDC: {\n [747 /* flowEVMMainnet */]: { oft: '0xAF54BE5B6eEc24d6BFACf1cce4eaF680A8239398', token: '0xF1815bd50389c46847f0Bda824eC8da914045D14' },\n [1 /* ethereum */]: { oft: '0xc026395860Db2d07ee33e05fE50ed7bD583189C7', token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' },\n [42161 /* arbitrum */]: { oft: '0xe8CDF27AcD73a434D661C84887215F7598e7d0d3', token: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' },\n [8453 /* base */]: { oft: '0x27a16dc786820B16E5c9028b75B99F6f604b5d26', token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },\n [10 /* optimism */]: { oft: '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0', token: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85' },\n [146 /* sonic */]: { oft: '0xA272fFe20cFfe769CdFc4b63088DCD2C82a2D8F9', token: '0x29219dd400f2Bf60E5a23d13Be72B486D4038894' },\n },\n /**\n * USDT — USDT bridged via Stargate v2.\n */\n USDT: {\n [747 /* flowEVMMainnet */]: { oft: '0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6', token: '0x674843C06FF83502ddb4D37c2E09C01cdA38cbc8' },\n [1 /* ethereum */]: { oft: '0x933597a323Eb81cAe705C5bC29985172fd5A3973', token: '0xdAC17F958D2ee523a2206206994597C13D831ec7' },\n [42161 /* arbitrum */]: { oft: '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0', token: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9' },\n [10 /* optimism */]: { oft: '0x19cFCE47eD54a88614648DC3f19A5980097007dD', token: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58' },\n },\n /**\n * USDF — USD Flow OFT. Bridges PYUSD (Ethereum) ↔ USDF (Flow EVM).\n */\n USDF: {\n [747 /* flowEVMMainnet */]: { oft: '0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed', token: '0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed' },\n [1 /* ethereum */]: { oft: '0xfa0e06b54986ad96de87a8c56fea76fbd8d493f8', token: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8' },\n },\n /**\n * PYUSD — PayPal USD bridged via OFTAdapter (Paxos / LayerZero).\n */\n PYUSD: {\n [747 /* flowEVMMainnet */]: { oft: '0x26d27d5AF2F6f1c14F40013C8619d97aaf015509', token: '0x99aF3EeA856556646C98c8B9b2548Fe815240750' },\n [42161 /* arbitrum */]: { oft: '0x3CD2b89C49D130C08f1d683225b2e5DeB63ff876', token: '0x46850aD61C2B7d64d08c9C754F45254596696984' },\n },\n /**\n * WFLOW — Wrapped FLOW NativeOFTAdapter (issued by Flow Foundation).\n */\n WFLOW: {\n [747 /* flowEVMMainnet */]: { oft: '0xd296588850bee2770136464ffdddd78c32f2a07c', token: '0xd296588850bee2770136464ffdddd78c32f2a07c' },\n [1 /* ethereum */]: { oft: '0xc1b45896b5fc9422a8f779653808297bb4f546f9', token: '0x5c147e74D63B1D31AA3Fd78Eb229B65161983B2b' },\n },\n /**\n * WETH — ETH OFT via Stargate v2. underlying = native ETH (no approval needed).\n */\n WETH: {\n [747 /* flowEVMMainnet */]: { oft: '0x45f1A95A4D3f3836523F5c83673c797f4d4d263B', token: '0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590' },\n [1 /* ethereum */]: { oft: '0x77b2043768d28E9C9aB44E1aBfC95944bcE57931', token: '0x0000000000000000000000000000000000000000' },\n [42161 /* arbitrum */]: { oft: '0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F', token: '0x0000000000000000000000000000000000000000' },\n [8453 /* base */]: { oft: '0xdc181Bd607330aeeBEF6ea62e03e5e1Fb4B6F7C7', token: '0x0000000000000000000000000000000000000000' },\n },\n /**\n * sUSDe — Ethena staked USDe (yield-bearing stablecoin).\n */\n sUSDe: {\n [1 /* ethereum */]: { oft: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', token: '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497' },\n [42161 /* arbitrum */]: { oft: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', token: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2' },\n [8453 /* base */]: { oft: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', token: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2' },\n [10 /* optimism */]: { oft: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', token: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2' },\n [56 /* bsc */]: { oft: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', token: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2' },\n },\n /**\n * USDe — Ethena USD stablecoin.\n */\n USDe: {\n [1 /* ethereum */]: { oft: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', token: '0x4c9EDD5852cd905f086C759E8383e09bff1E68B3' },\n [42161 /* arbitrum */]: { oft: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', token: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34' },\n [8453 /* base */]: { oft: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', token: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34' },\n [10 /* optimism */]: { oft: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', token: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34' },\n [56 /* bsc */]: { oft: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', token: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34' },\n },\n /**\n * weETH — Ether.Fi liquid restaking token.\n */\n weETH: {\n [1 /* ethereum */]: { oft: '0xcd2eb13d6831d4602d80e5db9230a57596cdca63', token: '0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee' },\n [8453 /* base */]: { oft: '0x04c0599ae5a44757c0af6f9ec3b93da8976c150a', token: '0x04c0599ae5a44757c0af6f9ec3b93da8976c150a' },\n [10 /* optimism */]: { oft: '0x5a7facb970d094b6c7ff1df0ea68d99e6e73cbff', token: '0x5a7facb970d094b6c7ff1df0ea68d99e6e73cbff' },\n [56 /* bsc */]: { oft: '0x04c0599ae5a44757c0af6f9ec3b93da8976c150a', token: '0x04c0599ae5a44757c0af6f9ec3b93da8976c150a' },\n [146 /* sonic */]: { oft: '0xa3d68b74bf0528fdd07263c60d6488749044914b', token: '0xa3d68b74bf0528fdd07263c60d6488749044914b' },\n },\n /**\n * rsETH — Kelp DAO liquid restaking token.\n */\n rsETH: {\n [1 /* ethereum */]: { oft: '0x85d456b2dff1fd8245387c0bfb64dfb700e98ef3', token: '0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7' },\n [42161 /* arbitrum */]: { oft: '0x4186bfc76e2e237523cbc30fd220fe055156b41f', token: '0x4186bfc76e2e237523cbc30fd220fe055156b41f' },\n [8453 /* base */]: { oft: '0x1bc71130a0e39942a7658878169764bbd8a45993', token: '0x1bc71130a0e39942a7658878169764bbd8a45993' },\n [10 /* optimism */]: { oft: '0x4186bfc76e2e237523cbc30fd220fe055156b41f', token: '0x4186bfc76e2e237523cbc30fd220fe055156b41f' },\n [146 /* sonic */]: { oft: '0xd75787ba9aba324420d522bda84c08c87e5099b1', token: '0xd75787ba9aba324420d522bda84c08c87e5099b1' },\n },\n /**\n * rswETH — Swell Network liquid restaking token.\n */\n rswETH: {\n [1 /* ethereum */]: { oft: '0x1486d39646cdee84619bd05997319545a8575079', token: '0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0' },\n [42161 /* arbitrum */]: { oft: '0xb1fe27b32ffb5ce54e272c096547f1e86c19e72f', token: '0xb1fe27b32ffb5ce54e272c096547f1e86c19e72f' },\n [8453 /* base */]: { oft: '0x850cdf416668210ed0c36bfff5d21921c7ada3b8', token: '0x850cdf416668210ed0c36bfff5d21921c7ada3b8' },\n },\n /**\n * USR — Resolv Labs USD stablecoin.\n */\n USR: {\n [1 /* ethereum */]: { oft: '0xd2ee2776f34ef4e7325745b06e6d464b08d4be0e', token: '0x66a1E37c9b0eAddca17d3662D6c05F4DECf3e110' },\n [42161 /* arbitrum */]: { oft: '0x2492d0006411af6c8bbb1c8afc1b0197350a79e9', token: '0x2492d0006411af6c8bbb1c8afc1b0197350a79e9' },\n [8453 /* base */]: { oft: '0x35e5db674d8e93a03d814fa0ada70731efe8a4b9', token: '0x35e5db674d8e93a03d814fa0ada70731efe8a4b9' },\n [56 /* bsc */]: { oft: '0x2492d0006411af6c8bbb1c8afc1b0197350a79e9', token: '0x2492d0006411af6c8bbb1c8afc1b0197350a79e9' },\n },\n /**\n * wstUSR — Resolv Labs wrapped staked USR (yield-bearing).\n */\n wstUSR: {\n [1 /* ethereum */]: { oft: '0xab17c1fe647c37ceb9b96d1c27dd189bf8451978', token: '0x1202F5C7b4B9E47a1A484E8B270be34dbbC75055' },\n [42161 /* arbitrum */]: { oft: '0x66cfbd79257dc5217903a36293120282548e2254', token: '0x66cfbd79257dc5217903a36293120282548e2254' },\n [8453 /* base */]: { oft: '0xb67675158b412d53fe6b68946483ba920b135ba1', token: '0xb67675158b412d53fe6b68946483ba920b135ba1' },\n [56 /* bsc */]: { oft: '0x4254813524695def4163a169e901f3d7a1a55429', token: '0x4254813524695def4163a169e901f3d7a1a55429' },\n },\n /**\n * USDtb — Ethena treasury-backed stablecoin.\n */\n USDtb: {\n [1 /* ethereum */]: { oft: '0xc708b6887db46005da033501f8aebee72d191a5d', token: '0xC139190F447e929f090Edeb554D95AbB8b18aC1C' },\n [42161 /* arbitrum */]: { oft: '0xc708b6887db46005da033501f8aebee72d191a5d', token: '0xc708b6887db46005da033501f8aebee72d191a5d' },\n [8453 /* base */]: { oft: '0xc708b6887db46005da033501f8aebee72d191a5d', token: '0xc708b6887db46005da033501f8aebee72d191a5d' },\n },\n} as const;\n\n/**\n * Uniswap V3 SwapRouter addresses per chain.\n * Used by curator swap helpers to build calldata for on-chain swaps.\n *\n * Note on struct differences:\n * - SwapRouter (Eth/Arb/Op, 0xE592...): exactInputSingle struct includes `deadline`\n * - SwapRouter02 (Base, 0x2626...): exactInputSingle struct does NOT include `deadline`\n * - FlowSwap V3 (Flow EVM, 0xeEDC...): derived from original UniV3, includes `deadline`\n */\nexport const UNISWAP_V3_ROUTERS: Record<number, string> = {\n [8453]: '0x2626664c2603336E57B271c5C0b26F421741e481', // Base — SwapRouter02 (no deadline)\n [1]: '0xE592427A0AEce92De3Edee1F18E0157C05861564', // Ethereum — SwapRouter\n [42161]: '0xE592427A0AEce92De3Edee1F18E0157C05861564', // Arbitrum — SwapRouter\n [10]: '0xE592427A0AEce92De3Edee1F18E0157C05861564', // Optimism — SwapRouter\n [747]: '0xeEDC6Ff75e1b10B903D9013c358e446a73d35341', // Flow EVM — FlowSwap V3 SwapRouter\n};\n\n/** Public RPC endpoints per chain for cross-chain reads */\nconst PUBLIC_RPCS: Record<number, string[]> = {\n 1: ['https://ethereum-rpc.publicnode.com', 'https://eth.drpc.org', 'https://eth.llamarpc.com'],\n 10: ['https://mainnet.optimism.io', 'https://optimism-rpc.publicnode.com'],\n 42161: ['https://arbitrum-one-rpc.publicnode.com', 'https://arbitrum.publicnode.com'],\n 8453: ['https://base-rpc.publicnode.com', 'https://base.llamarpc.com', 'https://mainnet.base.org'],\n 747: ['https://mainnet.evm.nodes.onflow.org'],\n 146: ['https://rpc.soniclabs.com'],\n 56: ['https://bsc-dataseed1.binance.org', 'https://bsc-dataseed2.binance.org'],\n};\n\n/**\n * Create a read-only ethers Provider for a given chain ID using public RPCs.\n * Returns null if no public RPC is configured for that chain.\n */\nexport function createChainProvider(chainId: number): Provider | null {\n const rpcs = PUBLIC_RPCS[chainId];\n if (!rpcs?.length) return null;\n return new JsonRpcProvider(rpcs[0], chainId, { staticNetwork: true });\n}\n\n/**\n * Recommended timeouts for cross-chain operations (milliseconds).\n * UIs should show a progress indicator and NOT timeout before these values.\n */\nexport const LZ_TIMEOUTS = {\n /** Poll interval between balance/event checks */\n POLL_INTERVAL: 30_000,\n /** Standard OFT bridge (shares or assets, non-Stargate) */\n OFT_BRIDGE: 900_000, // 15 min\n /** Stargate bridge (USDC, USDT, WETH) — slower due to pool mechanics */\n STARGATE_BRIDGE: 1_800_000, // 30 min\n /** LZ Read callback (async vault actions) */\n LZ_READ_CALLBACK: 900_000, // 15 min\n /** Compose delivery to hub (deposit from spoke) */\n COMPOSE_DELIVERY: 2_700_000, // 45 min\n /** Full spoke→hub→spoke redeem (all steps combined) */\n FULL_SPOKE_REDEEM: 3_600_000, // 60 min\n} as const;\n","import type { Signer, Provider, ContractTransactionReceipt } from \"ethers\";\n\n/** Addresses involved in vault operations. */\nexport interface VaultAddresses {\n /** Hub vault (diamond proxy) address. */\n vault: string;\n /** MoreVaultsEscrow address for cross-chain locking. */\n escrow?: string;\n /** OFTAdapter address for share token bridging (cross-chain only). */\n shareOFT?: string;\n /** OFT address for USDC bridging (cross-chain only). */\n usdcOFT?: string;\n /**\n * Expected EVM chain ID of the hub. When provided, SDK functions will\n * throw a clear WrongChainError if the signer is on a different chain.\n * Prevents silent failures when MetaMask is connected to the wrong network.\n */\n hubChainId?: number;\n}\n\n/** Result of a synchronous deposit or mint. */\nexport interface DepositResult {\n receipt: ContractTransactionReceipt;\n /** Number of vault shares minted. */\n shares: bigint;\n}\n\n/** Result of a synchronous redeem or withdraw. */\nexport interface RedeemResult {\n receipt: ContractTransactionReceipt;\n /** Number of underlying assets returned. */\n assets: bigint;\n}\n\n/** Result of an asynchronous cross-chain request. */\nexport interface AsyncRequestResult {\n receipt: ContractTransactionReceipt;\n /** bytes32 request GUID for tracking fulfillment. */\n guid: string;\n}\n\n/**\n * ActionType enum matching MoreVaultsLib.ActionType on-chain values.\n *\n * DEPOSIT = 0, MINT = 1, WITHDRAW = 2, REDEEM = 3,\n * MULTI_ASSETS_DEPOSIT = 4, ACCRUE_FEES = 5\n */\nexport const ActionType = {\n DEPOSIT: 0,\n MINT: 1,\n WITHDRAW: 2,\n REDEEM: 3,\n MULTI_ASSETS_DEPOSIT: 4,\n ACCRUE_FEES: 5,\n} as const;\n\nexport type ActionTypeValue = (typeof ActionType)[keyof typeof ActionType];\n\n/** Cross-chain request info returned by getRequestInfo. */\nexport interface CrossChainRequestInfo {\n initiator: string;\n timestamp: bigint;\n actionType: number;\n actionCallData: string;\n fulfilled: boolean;\n finalized: boolean;\n refunded: boolean;\n totalAssets: bigint;\n finalizationResult: bigint;\n amountLimit: bigint;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Curator Operations Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SwapParams {\n targetContract: string;\n tokenIn: string;\n tokenOut: string;\n maxAmountIn: bigint;\n minAmountOut: bigint;\n swapCallData: string;\n}\n\nexport interface BatchSwapParams {\n swaps: SwapParams[];\n}\n\nexport interface BridgeParams {\n oftToken: string;\n dstEid: number;\n amount: bigint;\n dstVault: string;\n refundAddress: string;\n}\n\nexport interface PendingAction {\n nonce: bigint;\n actionsData: string[];\n pendingUntil: bigint;\n isExecutable: boolean;\n}\n\nexport interface SubmitActionsResult {\n receipt: ContractTransactionReceipt;\n nonce: bigint;\n}\n\nexport type CuratorAction =\n | { type: 'swap'; params: SwapParams }\n | { type: 'batchSwap'; params: BatchSwapParams }\n | { type: 'erc4626Deposit'; vault: string; assets: bigint }\n | { type: 'erc4626Redeem'; vault: string; shares: bigint }\n | { type: 'erc7540RequestDeposit'; vault: string; assets: bigint }\n | { type: 'erc7540Deposit'; vault: string; assets: bigint }\n | { type: 'erc7540RequestRedeem'; vault: string; shares: bigint }\n | { type: 'erc7540Redeem'; vault: string; shares: bigint };\n\nexport interface CuratorVaultStatus {\n curator: string;\n timeLockPeriod: bigint;\n maxSlippagePercent: bigint;\n currentNonce: bigint;\n availableAssets: string[];\n lzAdapter: string;\n paused: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Vault Analysis Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface AssetInfo {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n}\n\nexport interface VaultAnalysis {\n /** All tokens the vault can hold/swap (curator-managed) */\n availableAssets: AssetInfo[];\n /** Tokens users can deposit */\n depositableAssets: AssetInfo[];\n /** Whether deposit whitelist is enabled (restricts who can deposit) */\n depositWhitelistEnabled: boolean;\n /** Registry address for global protocol whitelist checks */\n registryAddress: string | null;\n}\n\nexport interface AssetBalance extends AssetInfo {\n /** Raw balance held by the vault */\n balance: bigint;\n}\n\nexport interface VaultAssetBreakdown {\n /** Per-asset balances held by the vault on the hub chain */\n assets: AssetBalance[];\n /** totalAssets() as reported by the vault (all positions converted to underlying) */\n totalAssets: bigint;\n /** totalSupply() of vault shares */\n totalSupply: bigint;\n /** Vault underlying token decimals */\n underlyingDecimals: number;\n}\n\nexport type { Signer, Provider, ContractTransactionReceipt };\n","/**\n * Human-readable ABI fragments for MoreVaults diamond facets.\n * Extracted from compiled artifacts in out/.\n */\n\nexport const VAULT_ABI = [\n // ERC4626 core\n \"function deposit(uint256 assets, address receiver) returns (uint256 shares)\",\n \"function mint(uint256 shares, address receiver) returns (uint256 assets)\",\n \"function withdraw(uint256 assets, address receiver, address owner) returns (uint256 shares)\",\n \"function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)\",\n\n // Multi-asset deposit\n \"function deposit(address[] tokens, uint256[] assets, address receiver, uint256 minAmountOut) payable returns (uint256 shares)\",\n\n // Withdrawal queue\n \"function requestRedeem(uint256 shares, address onBehalfOf)\",\n \"function requestWithdraw(uint256 assets, address onBehalfOf)\",\n \"function clearRequest()\",\n \"function getWithdrawalRequest(address _owner) view returns (uint256 shares, uint256 timelockEndsAt)\",\n\n // Views\n \"function totalAssets() view returns (uint256)\",\n \"function totalSupply() view returns (uint256)\",\n \"function balanceOf(address account) view returns (uint256)\",\n \"function asset() view returns (address)\",\n \"function convertToShares(uint256 assets) view returns (uint256)\",\n \"function convertToAssets(uint256 shares) view returns (uint256)\",\n \"function previewDeposit(uint256 assets) view returns (uint256)\",\n \"function previewRedeem(uint256 shares) view returns (uint256)\",\n \"function paused() view returns (bool)\",\n\n // Events\n \"event Deposit(address indexed sender, address indexed owner, address[] tokens, uint256[] assets, uint256 shares)\",\n \"event Transfer(address indexed from, address indexed to, uint256 value)\",\n \"event WithdrawRequestCreated(address requester, uint256 sharesAmount, uint256 endsAt)\",\n \"event WithdrawRequestFulfilled(address requester, address receiver, uint256 sharesAmount, uint256 assetAmount)\",\n] as const;\n\nexport const BRIDGE_ABI = [\n \"function initVaultActionRequest(uint8 actionType, bytes actionCallData, uint256 amountLimit, bytes extraOptions) payable returns (bytes32 guid)\",\n \"function getRequestInfo(bytes32 guid) view returns (tuple(address initiator, uint64 timestamp, uint8 actionType, bytes actionCallData, bool fulfilled, bool finalized, bool refunded, uint256 totalAssets, uint256 finalizationResult, uint256 amountLimit))\",\n \"function getFinalizationResult(bytes32 guid) view returns (uint256 result)\",\n \"function oraclesCrossChainAccounting() view returns (bool)\",\n \"function quoteAccountingFee(bytes extraOptions) view returns (uint256 nativeFee)\",\n \"function accountingBridgeFacet() view returns (uint256 sum, bool isPositive)\",\n] as const;\n\nexport const CONFIG_ABI = [\n \"function getEscrow() view returns (address escrow)\",\n \"function getCrossChainAccountingManager() view returns (address)\",\n \"function isHub() view returns (bool)\",\n \"function getWithdrawalQueueStatus() view returns (bool)\",\n \"function getWithdrawalTimelock() view returns (uint64)\",\n \"function getWithdrawalFee() view returns (uint96)\",\n \"function getMaxWithdrawalDelay() view returns (uint32)\",\n \"function getAvailableAssets() view returns (address[])\",\n \"function getDepositableAssets() view returns (address[])\",\n \"function depositCapacity() view returns (uint256)\",\n \"function fee() view returns (uint96)\",\n \"function feeRecipient() view returns (address)\",\n \"function paused() view returns (bool)\",\n \"function maxDeposit(address receiver) view returns (uint256)\",\n] as const;\n\nexport const METADATA_ABI = [\n \"function name() view returns (string)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n] as const;\n\nexport const ERC20_ABI = [\n \"function approve(address spender, uint256 amount) returns (bool)\",\n \"function allowance(address owner, address spender) view returns (uint256)\",\n \"function balanceOf(address account) view returns (uint256)\",\n \"function transfer(address to, uint256 amount) returns (bool)\",\n] as const;\n\nexport const OFT_ABI = [\n \"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)\",\n \"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))\",\n] as const;\n\nexport const LZ_ENDPOINT_ABI = [\n \"function composeQueue(address from, address to, bytes32 guid, uint16 index) view returns (bytes32 messageHash)\",\n \"function lzCompose(address _from, address _to, bytes32 _guid, uint16 _index, bytes _message, bytes _extraData) payable\",\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Curator Operations ABIs\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * MulticallFacet ABI — curator action submission and execution with timelock.\n */\nexport const MULTICALL_ABI = [\n \"function submitActions(bytes[] actionsData) returns (uint256 nonce)\",\n \"function executeActions(uint256 actionsNonce)\",\n \"function getPendingActions(uint256 actionsNonce) view returns (bytes[] actionsData, uint256 pendingUntil)\",\n \"function getCurrentNonce() view returns (uint256)\",\n \"function vetoActions(uint256[] actionsNonces)\",\n] as const;\n\n/**\n * GenericDexFacet ABI — single and batch token swaps through any DEX aggregator.\n */\nexport const DEX_ABI = [\n \"function executeSwap(tuple(address targetContract, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 minAmountOut, bytes swapCallData) params) returns (uint256 amountOut)\",\n \"function executeBatchSwap(tuple(tuple(address targetContract, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 minAmountOut, bytes swapCallData)[] swaps) params) returns (uint256[] amountsOut)\",\n] as const;\n\n/**\n * BridgeFacet ABI — curator bridging and cross-chain request initiation.\n */\nexport const BRIDGE_FACET_ABI = [\n \"function executeBridging(address adapter, address token, uint256 amount, bytes bridgeSpecificParams) payable\",\n \"function initVaultActionRequest(uint8 actionType, bytes actionCallData, uint256 amountLimit, bytes extraOptions) payable returns (bytes32 guid)\",\n \"function executeRequest(bytes32 guid)\",\n] as const;\n\n/**\n * ERC7540Facet ABI — async deposit and redeem operations on ERC7540 vaults.\n */\nexport const ERC7540_FACET_ABI = [\n \"function erc7540RequestDeposit(address vault, uint256 assets) returns (uint256 requestId)\",\n \"function erc7540RequestRedeem(address vault, uint256 shares) returns (uint256 requestId)\",\n \"function erc7540Deposit(address vault, uint256 assets) returns (uint256 shares)\",\n \"function erc7540Redeem(address vault, uint256 shares) returns (uint256 assets)\",\n] as const;\n\n/**\n * ERC4626Facet ABI — synchronous deposit and redeem into whitelisted ERC-4626 vaults.\n */\nexport const ERC4626_FACET_ABI = [\n \"function erc4626Deposit(address vault, uint256 assets) returns (uint256 shares)\",\n \"function erc4626Redeem(address vault, uint256 shares) returns (uint256 assets)\",\n] as const;\n\n/**\n * ConfigurationFacet ABI — extended with curator-relevant read functions.\n */\nexport const CURATOR_CONFIG_ABI = [\n \"function curator() view returns (address)\",\n \"function timeLockPeriod() view returns (uint256)\",\n \"function getAvailableAssets() view returns (address[])\",\n \"function getMaxSlippagePercent() view returns (uint256)\",\n \"function getCrossChainAccountingManager() view returns (address)\",\n \"function paused() view returns (bool)\",\n] as const;\n\n/**\n * LzAdapter ABI — fee quoting for bridge and LZ Read operations.\n */\nexport const LZ_ADAPTER_ABI = [\n \"function quoteBridgeFee(bytes bridgeSpecificParams) view returns (uint256 nativeFee)\",\n \"function quoteReadFee(address[] vaults, uint32[] eids, bytes _extraOptions) view returns (tuple(uint256 nativeFee, uint256 lzTokenFee) fee)\",\n] as const;\n\n/**\n * Vault analysis ABIs — per-vault whitelist and registry reads.\n */\nexport const VAULT_ANALYSIS_ABI = [\n \"function getAvailableAssets() view returns (address[])\",\n \"function getDepositableAssets() view returns (address[])\",\n \"function isAssetAvailable(address asset) view returns (bool)\",\n \"function isAssetDepositable(address asset) view returns (bool)\",\n \"function isDepositWhitelistEnabled() view returns (bool)\",\n \"function getAvailableToDeposit(address depositor) view returns (uint256)\",\n \"function moreVaultsRegistry() view returns (address)\",\n] as const;\n\n/**\n * MoreVaultsRegistry ABI — global protocol and bridge whitelist checks.\n */\nexport const REGISTRY_ABI = [\n \"function isWhitelisted(address protocol) view returns (bool)\",\n \"function isBridgeAllowed(address bridge) view returns (bool)\",\n \"function getAllowedFacets() view returns (address[])\",\n] as const;\n","/**\n * Typed error classes for the MoreVaults SDK.\n *\n * Frontend code can use instanceof checks to handle errors programmatically:\n * catch (e) {\n * if (e instanceof InsufficientLiquidityError) { ... }\n * }\n */\n\nexport class MoreVaultsError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MoreVaultsError'\n }\n}\n\nexport class VaultPausedError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`)\n this.name = 'VaultPausedError'\n }\n}\n\nexport class CapacityFullError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} has reached deposit capacity. No more deposits accepted.`)\n this.name = 'CapacityFullError'\n }\n}\n\nexport class NotWhitelistedError extends MoreVaultsError {\n constructor(vault: string, user: string) {\n super(`[MoreVaults] Address ${user} is not whitelisted to deposit in vault ${vault}.`)\n this.name = 'NotWhitelistedError'\n }\n}\n\nexport class InsufficientLiquidityError extends MoreVaultsError {\n hubLiquid: bigint\n required: bigint\n constructor(vault: string, hubLiquid: bigint, required: bigint) {\n super(\n `[MoreVaults] Insufficient hub liquidity for redeem.\\n` +\n ` Hub liquid balance : ${hubLiquid}\\n` +\n ` Estimated required : ${required}\\n` +\n `Submitting this redeem will waste the LayerZero fee — the request will be auto-refunded.\\n` +\n `Ask the vault curator to repatriate liquidity from spoke chains first.`\n )\n this.name = 'InsufficientLiquidityError'\n this.hubLiquid = hubLiquid\n this.required = required\n }\n}\n\nexport class CCManagerNotConfiguredError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] CCManager not configured on vault ${vault}. Call setCrossChainAccountingManager(ccManagerAddress) as vault owner first.`)\n this.name = 'CCManagerNotConfiguredError'\n }\n}\n\nexport class EscrowNotConfiguredError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Escrow not configured for vault ${vault}. The registry must have an escrow set for this vault.`)\n this.name = 'EscrowNotConfiguredError'\n }\n}\n\nexport class NotHubVaultError extends MoreVaultsError {\n constructor(vault: string) {\n super(`[MoreVaults] Vault ${vault} is not a hub vault. Async flows (D4/D5/R5) only work on hub vaults.`)\n this.name = 'NotHubVaultError'\n }\n}\n\nexport class MissingEscrowAddressError extends MoreVaultsError {\n constructor() {\n super(`[MoreVaults] This flow requires an escrow address. Set VaultAddresses.escrow before calling async deposit/redeem flows.`)\n this.name = 'MissingEscrowAddressError'\n }\n}\n\nexport class WrongChainError extends MoreVaultsError {\n constructor(currentChainId: number, expectedChainId: number) {\n super(\n `Wrong network: wallet is on chain ${currentChainId}, but the vault hub requires chain ${expectedChainId}. Switch networks before proceeding.`,\n )\n this.name = 'WrongChainError'\n }\n}\n","/**\n * Utility helpers for the MoreVaults ethers.js v6 SDK.\n *\n * All reads use Provider (read-only). Writes use Signer.\n */\n\nimport { Contract, Interface, ZeroAddress } from \"ethers\";\nimport type { Provider, Signer } from \"ethers\";\nimport { BRIDGE_ABI, CONFIG_ABI, ERC20_ABI, VAULT_ABI } from \"./abis\";\n\n// Minimal ABI for Stargate type detection\nconst STARGATE_TYPE_ABI = [\n \"function stargateType() view returns (uint8)\",\n] as const;\n\n// Multicall3 — deployed at the same address on every EVM chain\nconst MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\nconst MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n] as const;\nimport type { CrossChainRequestInfo } from \"./types\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type VaultMode =\n | \"local\" // single-chain vault, no cross-chain\n | \"cross-chain-oracle\" // hub with oracle-based accounting (sync)\n | \"cross-chain-async\" // hub with off-chain accounting (async, D4/D5/R5)\n | \"paused\" // vault is paused\n | \"full\"; // deposit capacity reached\n\nexport interface VaultStatus {\n /** Vault operating mode — determines which SDK flow to use */\n mode: VaultMode;\n /** Which deposit function to call given the current configuration */\n recommendedDepositFlow: \"depositSimple\" | \"depositAsync\" | \"mintAsync\" | \"none\";\n /** Which redeem function to call given the current configuration */\n recommendedRedeemFlow: \"redeemShares\" | \"redeemAsync\" | \"none\";\n\n // ── Configuration ──────────────────────────────────────────────────────────\n isHub: boolean;\n isPaused: boolean;\n oracleAccountingEnabled: boolean;\n\n /** address(0) means CCManager is not set — async flows will fail */\n ccManager: string;\n /** address(0) means escrow is not configured in the registry */\n escrow: string;\n\n // ── Withdrawal queue ───────────────────────────────────────────────────────\n withdrawalQueueEnabled: boolean;\n /** Timelock duration in seconds (0 = no timelock) */\n withdrawalTimelockSeconds: bigint;\n\n // ── Capacity ───────────────────────────────────────────────────────────────\n /**\n * Remaining deposit capacity in underlying token decimals.\n * `type(uint256).max` = no cap configured (unlimited).\n * `0n` = vault is full — no more deposits accepted.\n * If `depositAccessRestricted = true`, this value is `type(uint256).max` but\n * deposits are still gated by whitelist or other access control.\n */\n remainingDepositCapacity: bigint;\n /**\n * True when `maxDeposit(address(0))` reverted, indicating the vault uses\n * whitelist or other access control to restrict who can deposit.\n */\n depositAccessRestricted: boolean;\n\n // ── Vault metrics ──────────────────────────────────────────────────────────\n underlying: string;\n totalAssets: bigint;\n totalSupply: bigint;\n /** Vault share token decimals. Use this for display — never hardcode 18. */\n decimals: number;\n /**\n * Price of 1 full share expressed in underlying token units.\n * = convertToAssets(10^decimals). Grows over time as the vault earns yield.\n */\n sharePrice: bigint;\n /**\n * Underlying token balance held directly on the hub chain.\n * This is the only portion that can be paid out to redeeming users immediately.\n * (= ERC-20.balanceOf(vault) on the hub)\n */\n hubLiquidBalance: bigint;\n /**\n * Approximate value deployed to spoke chains (totalAssets − hubLiquidBalance).\n * These funds are NOT immediately redeemable — the vault curator must\n * call executeBridging to repatriate them before large redeems can succeed.\n */\n spokesDeployedBalance: bigint;\n /**\n * Maximum assets that can be redeemed right now without curator intervention.\n * - For hub vaults: equals `hubLiquidBalance`.\n * - For local/oracle vaults: equals `totalAssets`.\n */\n maxImmediateRedeemAssets: bigint;\n\n // ── Issues — empty when everything is correctly configured ─────────────────\n /**\n * Human-readable list of configuration problems that would cause transactions\n * to fail. Empty array = vault is ready to use.\n */\n issues: string[];\n}\n\n/**\n * Ensure the spender has sufficient ERC-20 allowance; approve if not.\n *\n * @param signer Wallet signer with account attached\n * @param provider Read-only provider for allowance checks\n * @param token ERC-20 token address\n * @param spender Address to approve\n * @param amount Minimum required allowance\n */\nexport async function ensureAllowance(\n signer: Signer,\n provider: Provider,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20Read = new Contract(token, ERC20_ABI, provider);\n const current: bigint = await erc20Read.allowance(owner, spender);\n if (current < amount) {\n const erc20Write = new Contract(token, ERC20_ABI, signer);\n const tx = await erc20Write.approve(spender, amount);\n await tx.wait();\n }\n}\n\n/**\n * Quote the LayerZero native fee required for async vault actions.\n *\n * @param provider Read-only provider\n * @param vault Vault address (diamond proxy)\n * @param extraOptions Optional LZ extra options bytes (default 0x)\n * @returns Required native fee in wei\n */\nexport async function quoteLzFee(\n provider: Provider,\n vault: string,\n extraOptions: string = \"0x\"\n): Promise<bigint> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n const fee: bigint = await bridge.quoteAccountingFee(extraOptions);\n return fee;\n}\n\n/**\n * Check if a vault is operating in async mode (cross-chain hub with oracle OFF).\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns true if the vault requires async cross-chain flows\n */\nexport async function isAsyncMode(\n provider: Provider,\n vault: string\n): Promise<boolean> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [isHub, oraclesEnabled]: [boolean, boolean] = await Promise.all([\n config.isHub(),\n bridge.oraclesCrossChainAccounting(),\n ]);\n\n if (!isHub) return false;\n return !oraclesEnabled;\n}\n\n/**\n * Poll for async request completion status.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param guid Request GUID returned by the async flow\n * @returns Whether the request is fulfilled, finalized, and the result\n */\nexport async function getAsyncRequestStatus(\n provider: Provider,\n vault: string,\n guid: string\n): Promise<{ fulfilled: boolean; finalized: boolean; result: bigint }> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [info, finalizationResult]: [CrossChainRequestInfo, bigint] =\n await Promise.all([\n bridge.getRequestInfo(guid),\n bridge.getFinalizationResult(guid),\n ]);\n\n return {\n fulfilled: info.fulfilled,\n finalized: info.finalized,\n result: finalizationResult,\n };\n}\n\n/**\n * Read the full configuration and operational status of a vault.\n *\n * All independent reads are fired in parallel.\n *\n * @param provider Read-only provider\n * @param vault Vault address (diamond proxy)\n * @returns Full vault status snapshot\n */\nexport async function getVaultStatus(\n provider: Provider,\n vault: string\n): Promise<VaultStatus> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const configIface = new Interface(CONFIG_ABI as unknown as string[]);\n const bridgeIface = new Interface(BRIDGE_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // ── Batch 1: 12 calls → 1 eth_call via Multicall3.aggregate3 ─────────────\n const b1Calls = [\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"isHub\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"paused\") },\n { target: vault, allowFailure: false, callData: bridgeIface.encodeFunctionData(\"oraclesCrossChainAccounting\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getCrossChainAccountingManager\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getEscrow\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getWithdrawalQueueStatus\") },\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"getWithdrawalTimelock\") },\n // allowFailure=true: maxDeposit reverts on whitelisted vaults with address(0)\n { target: vault, allowFailure: true, callData: configIface.encodeFunctionData(\"maxDeposit\", [ZeroAddress]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"totalAssets\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"totalSupply\") },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const isHub = configIface.decodeFunctionResult(\"isHub\", b1[0].returnData)[0] as boolean;\n const isPaused = configIface.decodeFunctionResult(\"paused\", b1[1].returnData)[0] as boolean;\n const oraclesEnabled = bridgeIface.decodeFunctionResult(\"oraclesCrossChainAccounting\", b1[2].returnData)[0] as boolean;\n const ccManager = configIface.decodeFunctionResult(\"getCrossChainAccountingManager\", b1[3].returnData)[0] as string;\n const escrow = configIface.decodeFunctionResult(\"getEscrow\", b1[4].returnData)[0] as string;\n const withdrawalQueueEnabled = configIface.decodeFunctionResult(\"getWithdrawalQueueStatus\", b1[5].returnData)[0] as boolean;\n const withdrawalTimelockSeconds = configIface.decodeFunctionResult(\"getWithdrawalTimelock\", b1[6].returnData)[0] as bigint;\n // null sentinel: reverted means whitelist/ACL\n const maxDepositRaw = b1[7].success\n ? configIface.decodeFunctionResult(\"maxDeposit\", b1[7].returnData)[0] as bigint\n : null;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[8].returnData)[0] as string;\n const totalAssets = vaultIface.decodeFunctionResult(\"totalAssets\", b1[9].returnData)[0] as bigint;\n const totalSupply = vaultIface.decodeFunctionResult(\"totalSupply\", b1[10].returnData)[0] as bigint;\n const decimalsRaw = decimalsIface.decodeFunctionResult(\"decimals\", b1[11].returnData)[0];\n const decimalsNum = Number(decimalsRaw);\n const oneShare = 10n ** BigInt(decimalsNum);\n\n // ── Batch 2: 2 calls → 1 eth_call (depends on underlying + decimals) ─────\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n const b2Calls = [\n { target: underlying, allowFailure: false, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [vault]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"convertToAssets\", [oneShare]) },\n ];\n\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const hubLiquidBalance = erc20Iface.decodeFunctionResult(\"balanceOf\", b2[0].returnData)[0] as bigint;\n const sharePrice = vaultIface.decodeFunctionResult(\"convertToAssets\", b2[1].returnData)[0] as bigint;\n\n const spokesDeployedBalance: bigint = totalAssets > hubLiquidBalance ? totalAssets - hubLiquidBalance : 0n;\n\n // null = maxDeposit reverted.\n // For cross-chain-async hubs this is expected — the contract reverts with\n // NotAnERC4626CompatibleVault because maxDeposit is not meaningful in async mode.\n // Only treat the revert as \"whitelist/ACL\" when the vault is NOT a hub.\n const MAX_UINT256 = BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');\n const isCrossChainAsync = isHub && !oraclesEnabled;\n const depositAccessRestricted = maxDepositRaw === null && !isCrossChainAsync;\n const effectiveCapacity: bigint = maxDepositRaw === null ? MAX_UINT256 : maxDepositRaw!;\n\n // ── Derive mode ────────────────────────────────────────────────────────────\n let mode: VaultMode;\n if (isPaused) {\n mode = \"paused\";\n } else if (effectiveCapacity === 0n) {\n mode = \"full\";\n } else if (!isHub) {\n mode = \"local\";\n } else if (oraclesEnabled) {\n mode = \"cross-chain-oracle\";\n } else {\n mode = \"cross-chain-async\";\n }\n\n // ── Recommended flows ──────────────────────────────────────────────────────\n let recommendedDepositFlow: VaultStatus[\"recommendedDepositFlow\"];\n let recommendedRedeemFlow: VaultStatus[\"recommendedRedeemFlow\"];\n\n if (mode === \"paused\" || mode === \"full\") {\n recommendedDepositFlow = \"none\";\n recommendedRedeemFlow = mode === \"paused\" ? \"none\" : \"redeemShares\";\n } else if (mode === \"cross-chain-async\") {\n recommendedDepositFlow = \"depositAsync\";\n recommendedRedeemFlow = \"redeemAsync\";\n } else {\n // local or cross-chain-oracle\n recommendedDepositFlow = \"depositSimple\";\n recommendedRedeemFlow = \"redeemShares\";\n }\n\n // ── Issues ─────────────────────────────────────────────────────────────────\n const issues: string[] = [];\n\n if (isPaused) {\n issues.push(\"Vault is paused — no deposits or redeems are possible.\");\n }\n if (effectiveCapacity === 0n && !isPaused) {\n issues.push(\n \"Deposit capacity is full — increase depositCapacity via setDepositCapacity().\"\n );\n }\n if (isHub && !oraclesEnabled && ccManager === ZeroAddress) {\n issues.push(\n \"CCManager not configured — async flows will revert. Call setCrossChainAccountingManager(address) as vault owner.\"\n );\n }\n if (isHub && !oraclesEnabled && escrow === ZeroAddress) {\n issues.push(\n \"Escrow not configured in registry — async flows will revert. Set the escrow via the MoreVaultsRegistry.\"\n );\n }\n if (depositAccessRestricted) {\n issues.push(\"Deposit access is restricted (whitelist or other access control). Only approved addresses can deposit.\");\n }\n\n // ── maxImmediateRedeemAssets ────────────────────────────────────────────────\n const maxImmediateRedeemAssets: bigint = isHub && !oraclesEnabled ? hubLiquidBalance : totalAssets;\n\n if (isHub) {\n if (hubLiquidBalance === 0n) {\n issues.push(\n `Hub has no liquid assets (hubLiquidBalance = 0). All redeems will be auto-refunded until the curator repatriates funds from spokes via executeBridging().`\n );\n } else if (totalAssets > 0n && hubLiquidBalance * 10n < totalAssets) {\n const pct = Number((hubLiquidBalance * 10000n) / totalAssets) / 100;\n issues.push(\n `Low hub liquidity: ${hubLiquidBalance} units liquid on hub (${pct.toFixed(1)}% of TVL). ` +\n `Redeems above ${hubLiquidBalance} underlying units will be auto-refunded. ` +\n `Curator must call executeBridging() to repatriate from spokes.`\n );\n }\n if (spokesDeployedBalance > 0n) {\n const total = totalAssets;\n issues.push(\n `${spokesDeployedBalance} units (~${((Number(spokesDeployedBalance) / Number(total || 1n)) * 100).toFixed(1)}% of TVL) ` +\n `are deployed on spoke chains earning yield. These are NOT immediately redeemable — ` +\n `they require a curator repatriation (executeBridging) before users can withdraw them.`\n );\n }\n }\n\n return {\n mode,\n recommendedDepositFlow,\n recommendedRedeemFlow,\n isHub,\n isPaused,\n oracleAccountingEnabled: oraclesEnabled,\n ccManager,\n escrow,\n withdrawalQueueEnabled,\n withdrawalTimelockSeconds: BigInt(withdrawalTimelockSeconds),\n remainingDepositCapacity: effectiveCapacity,\n depositAccessRestricted,\n underlying,\n totalAssets,\n totalSupply,\n decimals: decimalsNum,\n sharePrice,\n hubLiquidBalance,\n spokesDeployedBalance,\n maxImmediateRedeemAssets,\n issues,\n };\n}\n\n/**\n * Detect whether an OFT address is a Stargate V2 pool by calling `stargateType()`.\n *\n * Stargate pools implement this function (returns 0=Pool, 1=OFT).\n * Standard OFTs revert because they don't have it.\n *\n * @param provider Read-only provider on the OFT's chain\n * @param oft OFT contract address\n * @returns true if the contract is a Stargate V2 pool/OFT\n */\nexport async function detectStargateOft(\n provider: Provider,\n oft: string\n): Promise<boolean> {\n try {\n const contract = new Contract(oft, STARGATE_TYPE_ABI, provider);\n await contract.stargateType();\n return true;\n } catch {\n return false;\n }\n}\n","import { Contract, AbiCoder, zeroPadValue, Signer, Provider } from \"ethers\";\nimport { ERC20_ABI, OFT_ABI, BRIDGE_ABI, LZ_ENDPOINT_ABI } from \"./abis\";\nimport type { ContractTransactionReceipt } from \"ethers\";\nimport { EID_TO_CHAIN_ID, OFT_ROUTES, createChainProvider } from \"./chains\";\nimport { detectStargateOft } from \"./utils\";\nimport { OMNI_FACTORY_ADDRESS } from \"./topology\";\n\n/** LZ Endpoint V2 address — same on all EVM chains */\nconst LZ_ENDPOINT = \"0x1a44076050125825900e736c501f859c50fe728c\";\n\nconst EMPTY_HASH = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\nconst RECEIVED_HASH = \"0x0000000000000000000000000000000000000000000000000000000000000001\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// D6 / D7 — Spoke → Hub, OFT Compose deposit\n// ---------------------------------------------------------------------------\n\n/**\n * D6 / D7 — Deposit from a spoke chain to the hub vault via OFT Compose.\n *\n * Bridges tokens from the spoke chain to the hub via LayerZero OFT, attaching a\n * composeMsg that instructs the hub-side MoreVaultsComposer to deposit into the vault.\n * Shares are delivered on the hub chain (local safeTransfer).\n *\n * - **D6 (oracle ON)**: composer calls `_depositAndSend` — shares arrive immediately on hub.\n * - **D7 (oracle OFF)**: composer calls `_initDeposit` — requires an additional LZ Read round-trip.\n *\n * TXs: 1 approve (if needed) + 1 OFT.send().\n *\n * @param signer - Wallet on the spoke chain.\n * @param spokeOFT - OFT/OFTAdapter address on the spoke chain.\n * @param composer - MoreVaultsComposer address on the hub chain.\n * @param hubEid - LayerZero EID for the hub chain.\n * @param spokeEid - LayerZero EID for the spoke chain — where shares are sent back.\n * @param amount - Amount of underlying tokens to bridge and deposit.\n * @param receiver - Address that will receive shares on the hub chain.\n * @param lzFee - Native fee for the OFT.send() call.\n * @param minMsgValue - Minimum msg.value the hub composer must receive (default 0).\n * @param minSharesOut - Minimum shares to receive after deposit (default 0).\n * @param minAmountLD - Minimum tokens received on hub after bridge (default: amount).\n * @param extraOptions - LZ extra options bytes (default '0x').\n * @returns Transaction receipt.\n */\nexport async function depositFromSpoke(\n signer: Signer,\n spokeOFT: string,\n composer: string,\n hubEid: number,\n spokeEid: number,\n amount: bigint,\n receiver: string,\n lzFee: bigint,\n minMsgValue: bigint = 0n,\n minSharesOut: bigint = 0n,\n minAmountLD?: bigint,\n extraOptions: string = \"0x\",\n): Promise<{ receipt: ContractTransactionReceipt }> {\n await ensureAllowance(signer, spokeOFT, spokeOFT, amount);\n\n const oft = new Contract(spokeOFT, OFT_ABI, signer);\n const refundAddress = await signer.getAddress();\n\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const composerBytes32 = zeroPadValue(composer, 32);\n\n // hopSendParam: dstEid = spokeEid → shares sent back to user on spoke via SHARE_OFT\n // Requires SHARE_OFT peers + enforcedOptions configured on both chains.\n // For Stargate OFTs: compose stays pending (msg.value=0), user retries via executeCompose.\n const hopSendParam = {\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 0n,\n minAmountLD: minSharesOut,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const coder = AbiCoder.defaultAbiCoder();\n const composeMsg = coder.encode(\n [\n \"tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd)\",\n \"uint256\",\n ],\n [hopSendParam, minMsgValue],\n );\n\n const sendParam = {\n dstEid: hubEid,\n to: composerBytes32,\n amountLD: amount,\n minAmountLD: minAmountLD ?? amount,\n extraOptions,\n composeMsg,\n oftCmd: \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// D7 -- Spoke -> Hub OFT Compose (oracle OFF, async)\n// ---------------------------------------------------------------------------\n\n/**\n * Alias: D7 — Spoke to hub deposit when oracle is OFF (async resolution).\n * Same interface as D6; the difference is handled server-side by the composer contract.\n */\nexport const depositFromSpokeAsync = depositFromSpoke;\n\n// ---------------------------------------------------------------------------\n// Fee quote helper\n// ---------------------------------------------------------------------------\n\n/**\n * Quote the LayerZero fee required for depositFromSpoke.\n *\n * @param provider Read-only provider on the SPOKE chain\n * @param spokeOFT OFT contract address on spoke chain\n * @param composer MoreVaultsComposer address on the hub chain\n * @param hubEid LayerZero EID for the hub chain\n * @param amount Amount of tokens to bridge\n * @param receiver Address that will receive vault shares\n * @param minMsgValue Same value you plan to pass to depositFromSpoke (default 0n)\n * @param minSharesOut Same value you plan to pass to depositFromSpoke (default 0n)\n * @param minAmountLD Minimum tokens on hub after bridge (default: amount)\n * @param extraOptions LZ extra options (default 0x)\n * @returns Native fee in wei\n */\nexport async function quoteDepositFromSpokeFee(\n provider: Provider,\n spokeOFT: string,\n composer: string,\n hubEid: number,\n spokeEid: number,\n amount: bigint,\n receiver: string,\n minMsgValue: bigint = 0n,\n minSharesOut: bigint = 0n,\n minAmountLD?: bigint,\n extraOptions: string = \"0x\"\n): Promise<bigint> {\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const composerBytes32 = zeroPadValue(composer, 32);\n\n // hopSendParam with dstEid=spokeEid → shares go back to spoke via SHARE_OFT\n const hopSendParam = {\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 0n,\n minAmountLD: minSharesOut,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const coder = AbiCoder.defaultAbiCoder();\n const composeMsgBytes = coder.encode(\n [\"tuple(uint32,bytes32,uint256,uint256,bytes,bytes,bytes)\", \"uint256\"],\n [\n [\n hopSendParam.dstEid,\n hopSendParam.to,\n hopSendParam.amountLD,\n hopSendParam.minAmountLD,\n hopSendParam.extraOptions,\n hopSendParam.composeMsg,\n hopSendParam.oftCmd,\n ],\n minMsgValue,\n ]\n );\n\n const sendParam = {\n dstEid: hubEid,\n to: composerBytes32,\n amountLD: amount,\n minAmountLD: minAmountLD ?? amount,\n extraOptions,\n composeMsg: composeMsgBytes,\n oftCmd: \"0x\",\n };\n\n const oft = new Contract(spokeOFT, OFT_ABI, provider);\n const fee = await oft.quoteSend(sendParam, false);\n return fee.nativeFee as bigint;\n}\n\n// ---------------------------------------------------------------------------\n// Stargate 2-TX compose helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Quote the ETH needed to execute a pending compose on the hub chain.\n *\n * For D7 (oracle OFF) vaults, the composer needs ETH to cover:\n * 1. `readFee` for `vault.initVaultActionRequest`\n * 2. `shareSendFee` for `SHARE_OFT.send()` to deliver shares to the spoke chain\n *\n * @param provider Read-only provider on the HUB chain\n * @param vault Vault address on the hub\n * @param spokeEid Destination EID for share delivery (optional — improves accuracy)\n * @param receiver Receiver address on the spoke chain (optional — improves accuracy)\n * @returns ETH amount in wei to send with executeCompose\n */\nexport async function quoteComposeFee(\n provider: Provider,\n vault: string,\n spokeEid?: number,\n receiver?: string,\n): Promise<bigint> {\n try {\n const vaultContract = new Contract(vault, BRIDGE_ABI, provider);\n const readFee: bigint = await vaultContract.quoteAccountingFee(\"0x\");\n\n // If spokeEid provided, also quote the SHARE_OFT send fee\n let shareSendFee = 0n;\n if (spokeEid && receiver) {\n try {\n const COMPOSER_ABI = [\"function SHARE_OFT() view returns (address)\"];\n const FACTORY_ABI = [\"function vaultComposer(address _vault) view returns (address)\"];\n const factory = new Contract(\"0x7bDB8B17604b03125eFAED33cA0c55FBf856BB0C\", FACTORY_ABI, provider);\n const composerAddr: string = await factory.vaultComposer(vault);\n const composer = new Contract(composerAddr, COMPOSER_ABI, provider);\n const shareOftAddr: string = await composer.SHARE_OFT();\n const shareOft = new Contract(shareOftAddr, OFT_ABI, provider);\n\n const receiverBytes32 = zeroPadValue(receiver, 32);\n const fee = await shareOft.quoteSend({\n dstEid: spokeEid,\n to: receiverBytes32,\n amountLD: 1_000_000n,\n minAmountLD: 0n,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n }, false);\n shareSendFee = fee.nativeFee as bigint;\n } catch { /* fallback to readFee only */ }\n }\n\n return (readFee + shareSendFee) * 110n / 100n; // 10% buffer\n } catch {\n return 500_000_000_000_000n; // 0.0005 ETH fallback\n }\n}\n\n/**\n * Execute a pending LZ compose on the hub chain (Stargate 2-TX flow, step 2).\n *\n * Calls `endpoint.lzCompose{value: fee}(from, to, guid, index, message, '0x')`.\n *\n * @param signer Wallet on the HUB chain\n * @param from Stargate pool address on hub (from ComposeSent event)\n * @param to MoreVaultsComposer address on hub\n * @param guid LayerZero GUID from the original OFT.send()\n * @param message Full compose message bytes (from ComposeSent event)\n * @param fee ETH to send (from quoteComposeFee)\n * @param index Compose index (default 0)\n * @returns Transaction receipt\n */\nexport async function executeCompose(\n signer: Signer,\n from: string,\n to: string,\n guid: string,\n message: string,\n fee: bigint,\n index: number = 0,\n): Promise<{ receipt: ContractTransactionReceipt }> {\n const endpoint = new Contract(LZ_ENDPOINT, LZ_ENDPOINT_ABI, signer);\n\n // Verify compose is still pending\n const hash: string = await endpoint.composeQueue(from, to, guid, index);\n if (hash === EMPTY_HASH) {\n throw new Error(\"Compose not found in queue (hash = 0). Never sent or wrong parameters.\");\n }\n if (hash === RECEIVED_HASH) {\n throw new Error(\"Compose already delivered — no action needed.\");\n }\n\n const tx = await endpoint.lzCompose(from, to, guid, index, message, \"0x\", {\n value: fee,\n gasLimit: 5_000_000n,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// Compose data types and waitForCompose\n// ---------------------------------------------------------------------------\n\n/**\n * Data needed to execute a pending LZ compose on the hub chain.\n * Returned by `depositFromSpoke` when the OFT is a Stargate V2 pool.\n * The SDK user must call `executeCompose()` with this data as TX2 on the hub.\n */\nexport interface ComposeData {\n /** LZ Endpoint address on the hub chain */\n endpoint: string\n /** The OFT/pool address that sent the compose (Stargate pool on hub) — resolved by waitForCompose */\n from: string\n /** MoreVaultsComposer address on the hub */\n to: string\n /** LayerZero GUID from the original OFT.send() */\n guid: string\n /** Compose index (default 0) */\n index: number\n /** Full compose message bytes — resolved by waitForCompose from ComposeSent event */\n message: string\n /** Whether this is a Stargate OFT (2-TX flow) */\n isStargate: boolean\n /** Hub chain ID */\n hubChainId: number\n /** Block number on hub chain right before depositFromSpoke TX — used to bound event scan */\n hubBlockStart: bigint\n}\n\n/** Minimal ABIs for helper functions used only in this file */\nconst FACTORY_COMPOSER_ABI_MIN = [\n \"function vaultComposer(address _vault) view returns (address)\",\n] as const;\n\nconst COMPOSER_SHARE_OFT_ABI = [\n \"function SHARE_OFT() view returns (address)\",\n] as const;\n\nconst OFT_PEERS_ABI = [\n \"function peers(uint32 eid) view returns (bytes32)\",\n] as const;\n\nconst OFT_TOKEN_ABI = [\n \"function token() view returns (address)\",\n] as const;\n\nconst OFT_QUOTE_OFT_ABI = [\n \"function quoteOFT(tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd) sendParam) view returns (tuple(uint256 minAmountLD, uint256 maxAmountLD), tuple(int256 feeAmountLD, string description)[], tuple(uint256 amountSentLD, uint256 amountReceivedLD))\",\n] as const;\n\n/**\n * Wait for a pending compose to appear in the LZ Endpoint's composeQueue on the hub chain.\n *\n * After `depositFromSpoke` sends tokens via Stargate, the LZ network delivers the message\n * to the hub chain. The endpoint stores the compose hash in `composeQueue` and emits\n * a `ComposeSent` event with the full message bytes.\n *\n * Strategy: scan ComposeSent events on the LZ Endpoint starting from `hubBlockStart`\n * (captured by `depositFromSpoke` right before TX1). We scan forward in 500-block chunks,\n * matching by composer address and receiver in the message body.\n *\n * @param hubProvider Read-only provider on the HUB chain\n * @param composeData Partial compose data (includes hubBlockStart, to, guid)\n * @param receiver Receiver address to match in the compose message\n * @param pollIntervalMs Polling interval (default 20s)\n * @param timeoutMs Timeout (default 30 min)\n * @returns Complete ComposeData ready for executeCompose\n */\nexport async function waitForCompose(\n hubProvider: Provider,\n composeData: ComposeData,\n receiver: string,\n pollIntervalMs = 20_000,\n timeoutMs = 1_800_000,\n): Promise<ComposeData> {\n const deadline = Date.now() + timeoutMs\n const composer = composeData.to.toLowerCase()\n const endpoint = composeData.endpoint\n const receiverNeedle = receiver.replace(/^0x/, '').toLowerCase()\n const startBlock = composeData.hubBlockStart\n\n // Collect Stargate OFT addresses on the hub chain\n const hubChainId = composeData.hubChainId\n const candidateAddresses: string[] = []\n for (const chainMap of Object.values(OFT_ROUTES)) {\n const entry = (chainMap as Record<number, { oft: string; token: string }>)[hubChainId]\n if (entry) candidateAddresses.push(entry.oft.toLowerCase())\n }\n\n // Filter to Stargate addresses on-chain\n const stargateChecks = await Promise.all(\n candidateAddresses.map(async (addr) => ({\n addr,\n isSg: await detectStargateOft(hubProvider, addr),\n })),\n )\n const knownFromAddresses = stargateChecks.filter((c) => c.isSg).map((c) => c.addr)\n\n // ComposeSent event ABI for getLogs\n const endpointContract = new Contract(endpoint, LZ_ENDPOINT_ABI, hubProvider)\n\n // ComposeSent event topic\n const COMPOSE_SENT_TOPIC = \"0x0c68e6a0b0fb0f33c52455a8da89b21fc640a3dd4a1b21d9bfcc8aeee4a43e84\"\n\n let attempt = 0\n let scannedUpTo = startBlock - 1n\n\n while (Date.now() < deadline) {\n attempt++\n const elapsed = Math.round((Date.now() - (deadline - timeoutMs)) / 1000)\n\n try {\n const currentBlock = BigInt(await hubProvider.getBlockNumber())\n const chunkSize = 500n\n let from = scannedUpTo + 1n\n\n while (from <= currentBlock) {\n const chunkEnd = from + chunkSize > currentBlock ? currentBlock : from + chunkSize\n\n try {\n const logs = await hubProvider.getLogs({\n address: endpoint,\n topics: [COMPOSE_SENT_TOPIC],\n fromBlock: `0x${from.toString(16)}`,\n toBlock: `0x${chunkEnd.toString(16)}`,\n })\n\n for (const log of logs) {\n // ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message)\n // All params are non-indexed — decode from data\n try {\n const coder = AbiCoder.defaultAbiCoder()\n const decoded = coder.decode(\n ['address', 'address', 'bytes32', 'uint16', 'bytes'],\n log.data,\n )\n const logFrom = (decoded[0] as string).toLowerCase()\n const logTo = (decoded[1] as string).toLowerCase()\n const logGuid = decoded[2] as string\n const logIndex = Number(decoded[3])\n const logMessage = decoded[4] as string\n\n if (\n logTo === composer &&\n logMessage.toLowerCase().includes(receiverNeedle)\n ) {\n // Verify this compose is still pending in composeQueue\n const hash: string = await endpointContract.composeQueue(\n logFrom, composer, logGuid, logIndex,\n )\n\n if (hash !== EMPTY_HASH && hash !== RECEIVED_HASH) {\n console.log(`[${elapsed}s] Poll #${attempt} — compose found! (block ${log.blockNumber})`)\n return {\n ...composeData,\n from: decoded[0] as string,\n to: composeData.to,\n guid: logGuid,\n index: logIndex,\n message: logMessage,\n }\n }\n }\n } catch { /* decode failed — skip log */ }\n }\n } catch {\n // Chunk failed (RPC limit) — break inner loop, will retry next poll\n break\n }\n\n from = chunkEnd + 1n\n }\n\n scannedUpTo = currentBlock\n } catch {\n // getBlockNumber failed — retry next poll\n }\n\n // Also try composeQueue directly with spoke GUID (works when GUIDs match)\n let guidMatchFound = false\n for (const fromAddr of knownFromAddresses) {\n try {\n const hash: string = await endpointContract.composeQueue(\n fromAddr, composer, composeData.guid, 0,\n )\n if (hash !== EMPTY_HASH && hash !== RECEIVED_HASH) {\n console.log(`[${elapsed}s] Poll #${attempt} — composeQueue confirms pending (GUID match), re-scanning for message...`)\n scannedUpTo = startBlock - 1n\n guidMatchFound = true\n }\n } catch { /* continue */ }\n }\n\n if (!guidMatchFound) {\n console.log(`[${elapsed}s] Poll #${attempt} — compose not found yet, waiting ${pollIntervalMs / 1000}s...`)\n }\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs))\n }\n\n throw new Error(\n `Timeout waiting for compose after ${timeoutMs / 60_000} min. Check LayerZero scan for composer ${composeData.to}.`,\n )\n}\n","/**\n * Pre-flight validation helpers for MoreVaults ethers.js v6 SDK flows.\n *\n * Each function reads on-chain state and throws a descriptive error BEFORE\n * the actual contract call, so developers see a clear, actionable message\n * instead of a raw VM revert.\n */\n\nimport { Contract, ZeroAddress } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { CONFIG_ABI, BRIDGE_ABI, VAULT_ABI, ERC20_ABI, OFT_ABI } from \"./abis\";\nimport { InsufficientLiquidityError } from \"./errors\";\nimport { detectStargateOft } from \"./utils\";\nimport { EID_TO_CHAIN_ID, createChainProvider } from \"./chains\";\nimport { quoteComposeFee } from \"./crossChainFlows\";\n\n/**\n * Pre-flight checks for async cross-chain flows (D4 / D5 / R5).\n *\n * Validates that:\n * 1. The CCManager is configured on the vault.\n * 2. An escrow is registered in the vault's registry.\n * 3. The vault is a hub (required for async flows).\n * 4. The vault does NOT have oracle-based cross-chain accounting enabled\n * (oracle-on vaults should use depositSimple / depositCrossChainOracleOn).\n * 5. The vault is not paused.\n *\n * All reads that are independent of each other are executed in parallel via\n * Promise.all to minimise latency.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n * @param escrow Escrow address from VaultAddresses\n */\nexport async function preflightAsync(\n provider: Provider,\n vault: string,\n escrow: string\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n // Parallel read: ccManager, escrow, isHub, oraclesCrossChainAccounting, paused\n const [ccManager, registeredEscrow, isHub, oraclesEnabled, isPaused] =\n await Promise.all([\n config.getCrossChainAccountingManager() as Promise<string>,\n config.getEscrow() as Promise<string>,\n config.isHub() as Promise<boolean>,\n bridge.oraclesCrossChainAccounting() as Promise<boolean>,\n config.paused() as Promise<boolean>,\n ]);\n\n if (ccManager === ZeroAddress) {\n throw new Error(\n `[MoreVaults] CCManager not configured on vault ${vault}. Call setCrossChainAccountingManager(ccManagerAddress) as vault owner first.`\n );\n }\n\n if (registeredEscrow === ZeroAddress) {\n throw new Error(\n `[MoreVaults] Escrow not configured for vault ${vault}. The registry must have an escrow set for this vault.`\n );\n }\n\n if (!isHub) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is not a hub vault. Async flows (D4/D5/R5) only work on hub vaults.`\n );\n }\n\n if (oraclesEnabled) {\n throw new Error(\n `[MoreVaults] Vault ${vault} has oracle-based cross-chain accounting enabled. Use depositSimple/depositCrossChainOracleOn instead of async flows.`\n );\n }\n\n if (isPaused) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`\n );\n }\n}\n\n/**\n * Pre-flight liquidity check for async redeem (R5).\n *\n * Reads the hub's liquid balance of the underlying token and compares it\n * against the assets the user expects to receive. If the hub does not hold\n * enough liquid assets the redeem will be auto-refunded after the LZ round-trip,\n * wasting the LayerZero fee.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n * @param shares Shares the user intends to redeem\n */\nexport async function preflightRedeemLiquidity(\n provider: Provider,\n vault: string,\n shares: bigint\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n // Check if this is a hub vault without oracle accounting.\n // Only those vaults can have liquidity stranded on spoke chains.\n const [isHub, oraclesEnabled]: [boolean, boolean] = await Promise.all([\n config.isHub(),\n bridge.oraclesCrossChainAccounting(),\n ]);\n\n // Non-hub vaults and oracle-on hubs hold all redeemable assets locally —\n // no liquidity gap is possible, so skip the check.\n if (!isHub || oraclesEnabled) return;\n\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const underlying: string = await vaultContract.asset();\n\n const underlyingContract = new Contract(underlying, ERC20_ABI, provider);\n // NOTE: previewRedeem reverts on async cross-chain vaults (disabled by design).\n // convertToAssets is always safe and gives a correct lower-bound estimate.\n const [hubLiquid, assetsNeeded]: [bigint, bigint] = await Promise.all([\n underlyingContract.balanceOf(vault),\n vaultContract.convertToAssets(shares),\n ]);\n\n if (hubLiquid < assetsNeeded) {\n throw new InsufficientLiquidityError(vault, hubLiquid, assetsNeeded);\n }\n}\n\n/**\n * Pre-flight checks for synchronous deposit flows (D1 / D3).\n *\n * Validates that:\n * 1. The vault is not paused.\n * 2. The vault still has deposit capacity (maxDeposit > 0).\n *\n * Both reads are executed in parallel.\n *\n * @param provider Read-only provider for contract reads\n * @param vault Vault address (diamond proxy)\n */\nexport async function preflightSync(\n provider: Provider,\n vault: string\n): Promise<void> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n\n // Run paused and maxDeposit in parallel.\n // maxDeposit(ZeroAddress) may REVERT on whitelisted vaults — catch separately.\n const [isPaused, depositCapResult] = await Promise.all([\n config.paused() as Promise<boolean>,\n (config.maxDeposit(ZeroAddress) as Promise<bigint>).catch(() => null as null),\n ]);\n\n if (isPaused) {\n throw new Error(\n `[MoreVaults] Vault ${vault} is paused. Cannot perform any actions.`\n );\n }\n\n // null means maxDeposit reverted → whitelist vault — skip capacity check\n // (the user may still be whitelisted; canDeposit will do user-specific check)\n if (depositCapResult !== null && depositCapResult === 0n) {\n throw new Error(\n `[MoreVaults] Vault ${vault} has reached deposit capacity. No more deposits accepted.`\n );\n }\n}\n\n/**\n * Pre-flight checks for spoke-to-hub deposits (D6 / D7 via OFT Compose).\n *\n * Validates that:\n * 1. User has enough tokens on the spoke chain to deposit.\n * 2. User has enough native gas on the spoke chain for TX1 (OFT.send).\n * 3. For Stargate OFTs (2-TX flow): user has enough ETH on the hub chain for TX2.\n *\n * @param spokeProvider Read-only provider on the SPOKE chain\n * @param vault Vault address\n * @param spokeOFT OFT contract address on the spoke chain\n * @param hubEid LZ EID for the hub chain\n * @param spokeEid LZ EID for the spoke chain\n * @param amount Amount of tokens to deposit\n * @param userAddress User's wallet address\n * @param lzFee LZ fee for TX1 (from quoteDepositFromSpokeFee)\n * @returns Object with validated balances for UI display\n */\nexport async function preflightSpokeDeposit(\n spokeProvider: Provider,\n vault: string,\n spokeOFT: string,\n hubEid: number,\n spokeEid: number,\n amount: bigint,\n userAddress: string,\n lzFee: bigint,\n): Promise<{\n spokeTokenBalance: bigint\n spokeNativeBalance: bigint\n hubNativeBalance: bigint\n estimatedComposeFee: bigint\n isStargate: boolean\n}> {\n // Read the underlying token address from the OFT\n const OFT_TOKEN_ABI = [\"function token() view returns (address)\"] as const;\n const oftContract = new Contract(spokeOFT, OFT_TOKEN_ABI, spokeProvider);\n const spokeToken: string = await oftContract.token();\n\n // Check token balance + native balance on spoke in parallel\n const tokenContract = new Contract(spokeToken, ERC20_ABI, spokeProvider);\n const [spokeTokenBalance, spokeNativeBalance]: [bigint, bigint] = await Promise.all([\n tokenContract.balanceOf(userAddress),\n spokeProvider.getBalance(userAddress),\n ]);\n\n // 1. Check token balance\n if (spokeTokenBalance < amount) {\n throw new Error(\n `[MoreVaults] Insufficient token balance on spoke chain.\\n` +\n ` Need: ${amount}\\n` +\n ` Have: ${spokeTokenBalance}\\n` +\n ` Token: ${spokeToken}`,\n );\n }\n\n // 2. Check native gas for TX1 (lzFee + gas buffer)\n const gasBuffer = 500_000_000_000_000n; // 0.0005 ETH\n if (spokeNativeBalance < lzFee + gasBuffer) {\n throw new Error(\n `[MoreVaults] Insufficient native gas on spoke chain for TX1.\\n` +\n ` Need: ~${lzFee + gasBuffer} wei (LZ fee + gas)\\n` +\n ` Have: ${spokeNativeBalance} wei`,\n );\n }\n\n // 3. For Stargate OFTs: check ETH on hub for TX2 (compose retry)\n const isStargate = await detectStargateOft(spokeProvider, spokeOFT);\n\n let hubNativeBalance = 0n;\n let estimatedComposeFee = 0n;\n\n if (isStargate) {\n const hubChainId = EID_TO_CHAIN_ID[hubEid];\n const hubProvider = createChainProvider(hubChainId);\n if (hubProvider) {\n [hubNativeBalance, estimatedComposeFee] = await Promise.all([\n hubProvider.getBalance(userAddress),\n quoteComposeFee(hubProvider, vault, spokeEid, userAddress),\n ]);\n\n const hubGasBuffer = 300_000_000_000_000n; // 0.0003 ETH\n const totalNeeded = estimatedComposeFee + hubGasBuffer;\n\n if (hubNativeBalance < totalNeeded) {\n throw new Error(\n `[MoreVaults] Insufficient ETH on hub chain for TX2 (compose retry).\\n` +\n ` This is a Stargate 2-TX flow — TX2 requires ETH on the hub chain.\\n` +\n ` Need: ~${totalNeeded} wei (compose fee ${estimatedComposeFee} + gas)\\n` +\n ` Have: ${hubNativeBalance} wei\\n` +\n ` Short: ${totalNeeded - hubNativeBalance} wei\\n` +\n ` Send ETH to ${userAddress} on chainId ${hubChainId} before depositing.`,\n );\n }\n }\n }\n\n return {\n spokeTokenBalance,\n spokeNativeBalance,\n hubNativeBalance,\n estimatedComposeFee,\n isStargate,\n };\n}\n\n/**\n * Pre-flight checks for spoke→hub→spoke redeem (R6 + R1 + R7).\n *\n * Validates that:\n * 1. User has shares on the spoke chain.\n * 2. User has enough native gas on the spoke for TX1.\n * 3. User has enough native gas on the hub for TX2 (redeem) + TX3 (asset bridge).\n *\n * @param route SpokeRedeemRoute from resolveRedeemAddresses\n * @param shares Shares the user intends to redeem\n * @param userAddress User's wallet address\n * @param shareBridgeFee LZ fee for share bridge (TX1)\n * @returns Validated balances for UI display\n */\nexport async function preflightSpokeRedeem(\n route: {\n hubChainId: number\n spokeChainId: number\n hubEid: number\n spokeEid: number\n hubAsset: string\n spokeShareOft: string\n hubAssetOft: string\n spokeAsset: string\n isStargate: boolean\n },\n shares: bigint,\n userAddress: string,\n shareBridgeFee: bigint,\n): Promise<{\n sharesOnSpoke: bigint\n spokeNativeBalance: bigint\n hubNativeBalance: bigint\n estimatedAssetBridgeFee: bigint\n estimatedAssetsOut: bigint\n hubLiquidBalance: bigint\n}> {\n const spokeProvider = createChainProvider(route.spokeChainId);\n const hubProvider = createChainProvider(route.hubChainId);\n if (!spokeProvider) throw new Error(`No public RPC for spoke chainId ${route.spokeChainId}`);\n if (!hubProvider) throw new Error(`No public RPC for hub chainId ${route.hubChainId}`);\n\n // Parallel reads: shares on spoke, native balances\n const spokeShareContract = new Contract(route.spokeShareOft, ERC20_ABI, spokeProvider);\n const [sharesOnSpoke, spokeNativeBalance, hubNativeBalance]: [bigint, bigint, bigint] =\n await Promise.all([\n spokeShareContract.balanceOf(userAddress),\n spokeProvider.getBalance(userAddress),\n hubProvider.getBalance(userAddress),\n ]);\n\n // 1. Check shares\n if (sharesOnSpoke < shares) {\n throw new Error(\n `[MoreVaults] Insufficient shares on spoke chain.\\n` +\n ` Need: ${shares}\\n` +\n ` Have: ${sharesOnSpoke}\\n` +\n ` Token: ${route.spokeShareOft}`,\n );\n }\n\n // 2. Check spoke gas for TX1\n const spokeGasBuffer = 500_000_000_000_000n; // 0.0005 ETH\n if (spokeNativeBalance < shareBridgeFee + spokeGasBuffer) {\n throw new Error(\n `[MoreVaults] Insufficient native gas on spoke for TX1 (share bridge).\\n` +\n ` Need: ~${shareBridgeFee + spokeGasBuffer} wei (LZ fee + gas)\\n` +\n ` Have: ${spokeNativeBalance} wei`,\n );\n }\n\n // 3. Estimate asset bridge fee (TX3) and check hub gas\n let estimatedAssetBridgeFee = 0n;\n\n try {\n const toBytes32 = `0x${userAddress.replace(/^0x/, '').padStart(64, '0')}`;\n const dummyAmount = 1_000_000n; // 1 USDC for fee estimation\n const hubOft = new Contract(route.hubAssetOft, OFT_ABI, hubProvider);\n const feeResult = await hubOft.quoteSend({\n dstEid: route.spokeEid,\n to: toBytes32,\n amountLD: dummyAmount,\n minAmountLD: dummyAmount * 99n / 100n,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: route.isStargate ? \"0x01\" : \"0x\",\n }, false);\n estimatedAssetBridgeFee = feeResult.nativeFee as bigint;\n } catch {\n estimatedAssetBridgeFee = 300_000_000_000_000n; // 0.0003 ETH fallback\n }\n\n const hubGasBuffer = 300_000_000_000_000n; // 0.0003 ETH for gas (TX2 + TX3)\n const totalHubNeeded = estimatedAssetBridgeFee + hubGasBuffer;\n\n if (hubNativeBalance < totalHubNeeded) {\n throw new Error(\n `[MoreVaults] Insufficient ETH on hub chain for TX2 (redeem) + TX3 (asset bridge).\\n` +\n ` Need: ~${totalHubNeeded} wei (LZ fee ${estimatedAssetBridgeFee} + gas)\\n` +\n ` Have: ${hubNativeBalance} wei\\n` +\n ` Short: ${totalHubNeeded - hubNativeBalance} wei\\n` +\n ` Send ETH to ${userAddress} on chainId ${route.hubChainId} before redeeming.`,\n );\n }\n\n return {\n sharesOnSpoke,\n spokeNativeBalance,\n hubNativeBalance,\n estimatedAssetBridgeFee,\n estimatedAssetsOut: 0n,\n hubLiquidBalance: 0n,\n };\n}\n","import type { Signer } from 'ethers'\nimport { WrongChainError } from './errors'\n\n/**\n * Validate that the signer is connected to the expected chain.\n * Only validates if hubChainId is provided — opt-in, non-breaking.\n */\nexport async function validateWalletChain(signer: Signer, hubChainId?: number): Promise<void> {\n if (!hubChainId) return\n const network = await signer.provider?.getNetwork()\n if (!network) return\n const current = Number(network.chainId)\n if (current !== hubChainId) {\n throw new WrongChainError(current, hubChainId)\n }\n}\n","import { Contract, AbiCoder, Signer, ZeroAddress } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { VAULT_ABI, BRIDGE_ABI, ERC20_ABI } from \"./abis\";\nimport {\n VaultAddresses,\n DepositResult,\n AsyncRequestResult,\n ActionType,\n} from \"./types\";\nimport { preflightAsync, preflightSync } from \"./preflight\";\nimport { EscrowNotConfiguredError, VaultPausedError, CapacityFullError } from \"./errors\";\nimport { validateWalletChain } from \"./chainValidation\";\nimport { getVaultStatus, quoteLzFee } from \"./utils\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n * Sends an approve TX only if current allowance is insufficient.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// D1 -- Simple deposit (1 TX, sync)\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit `assets` of the vault's underlying token and receive shares.\n *\n * TXs: 1 approve (if needed) + 1 deposit.\n *\n * @param signer - Wallet that holds the underlying tokens.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param assets - Amount of underlying tokens to deposit.\n * @param receiver - Address that will receive the minted shares.\n * @returns Shares minted and the transaction receipt.\n */\nexport async function depositSimple(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string\n): Promise<DepositResult> {\n const provider = signer.provider!;\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate vault is operational and accepting deposits\n await preflightSync(provider, addresses.vault);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n await ensureAllowance(signer, underlying, addresses.vault, assets);\n\n // Call the single-asset deposit overload: deposit(uint256, address)\n const tx = await vault[\"deposit(uint256,address)\"](assets, receiver);\n const receipt = await tx.wait();\n\n // Extract shares from the return value via Transfer event (from 0x0 = mint)\n let shares = 0n;\n for (const log of receipt.logs) {\n try {\n const parsed = vault.interface.parseLog({\n topics: log.topics as string[],\n data: log.data,\n });\n if (\n parsed &&\n parsed.name === \"Transfer\" &&\n parsed.args[0] === \"0x0000000000000000000000000000000000000000\"\n ) {\n shares = parsed.args[2];\n break;\n }\n } catch {\n // skip non-matching logs\n }\n }\n\n return { receipt, shares };\n}\n\n// ---------------------------------------------------------------------------\n// D2 -- Multi-asset deposit\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit multiple tokens in a single transaction.\n *\n * TXs: N approves (if needed) + 1 deposit.\n *\n * @param signer - Wallet holding the tokens.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param tokens - Array of token addresses to deposit.\n * @param amounts - Corresponding amounts for each token.\n * @param receiver - Address that will receive the minted shares.\n * @param minShares - Minimum acceptable shares (slippage protection).\n * @returns Shares minted and the transaction receipt.\n */\nexport async function depositMultiAsset(\n signer: Signer,\n addresses: VaultAddresses,\n tokens: string[],\n amounts: bigint[],\n receiver: string,\n minShares: bigint\n): Promise<DepositResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Approve each token\n for (let i = 0; i < tokens.length; i++) {\n await ensureAllowance(signer, tokens[i], addresses.vault, amounts[i]);\n }\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault[\n \"deposit(address[],uint256[],address,uint256)\"\n ](tokens, amounts, receiver, minShares);\n const receipt = await tx.wait();\n\n let shares = 0n;\n for (const log of receipt.logs) {\n try {\n const parsed = vault.interface.parseLog({\n topics: log.topics as string[],\n data: log.data,\n });\n if (parsed && parsed.name === \"Deposit\") {\n shares = parsed.args[4]; // 5th arg = shares\n break;\n }\n } catch {\n // skip\n }\n }\n\n return { receipt, shares };\n}\n\n// ---------------------------------------------------------------------------\n// D3 -- Cross-chain oracle ON (transparent, identical to D1)\n// ---------------------------------------------------------------------------\n\n/**\n * Deposit when cross-chain oracle accounting is ON.\n * Behaves identically to a simple deposit because oracle provides\n * synchronous pricing.\n *\n * TXs: 1 approve (if needed) + 1 deposit.\n */\nexport const depositCrossChainOracleOn = depositSimple;\n\n// ---------------------------------------------------------------------------\n// D4 -- Cross-chain oracle OFF, async DEPOSIT\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain deposit request.\n *\n * CRITICAL: tokens are approved to the **escrow** address, not the vault.\n *\n * TXs: 1 approve to escrow (if needed) + 1 initVaultActionRequest.\n * After this call, a LayerZero message is sent; the caller must wait for\n * cross-chain fulfillment before shares are minted.\n *\n * @param signer - Wallet holding the underlying tokens.\n * @param addresses - Must include `vault` and `escrow`.\n * @param assets - Amount of underlying tokens to deposit.\n * @param receiver - Address that will receive shares on fulfillment.\n * @param lzFee - Native fee for LayerZero message (use `quoteLzFee`).\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function depositAsync(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n // CRITICAL: approve ESCROW, not vault\n await ensureAllowance(signer, underlying, escrow, assets);\n\n // Encode parameters only (no selector) — contracts use abi.decode on these bytes\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\"],\n [assets, receiver]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.DEPOSIT,\n actionCallData,\n 0,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.DEPOSIT,\n actionCallData,\n 0, // amountLimit = 0 for deposits (minAmountOut handled by cross-chain manager)\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n// ---------------------------------------------------------------------------\n// D5 -- Cross-chain oracle OFF, async MINT\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain mint request (exact shares).\n *\n * CRITICAL: tokens are approved to the **escrow** address, not the vault.\n *\n * TXs: 1 approve to escrow for maxAssets (if needed) + 1 initVaultActionRequest.\n *\n * @param signer - Wallet holding the underlying tokens.\n * @param addresses - Must include `vault` and `escrow`.\n * @param shares - Exact number of shares to mint.\n * @param maxAssets - Maximum underlying tokens to spend (slippage cap).\n * @param receiver - Address that will receive shares on fulfillment.\n * @param lzFee - Native fee for LayerZero message.\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function mintAsync(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n maxAssets: bigint,\n receiver: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const underlying: string = await vault.asset();\n\n // CRITICAL: approve ESCROW for maxAssets\n await ensureAllowance(signer, underlying, escrow, maxAssets);\n\n // Encode parameters only (no selector) — contracts use abi.decode on these bytes\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\"],\n [shares, receiver]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.MINT,\n actionCallData,\n maxAssets,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.MINT,\n actionCallData,\n maxAssets,\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n/**\n * Smart deposit — auto-selects the correct flow based on vault configuration.\n *\n * Calls getVaultStatus internally to determine the vault mode, then dispatches\n * to the appropriate flow:\n * - local / cross-chain-oracle → depositSimple\n * - cross-chain-async → depositAsync (quotes LZ fee automatically)\n *\n * @param signer Wallet signer with account attached\n * @param provider Read-only provider for on-chain reads\n * @param addresses Vault address set (`escrow` required for async vaults)\n * @param assets Amount of underlying to deposit\n * @param receiver Address that will receive shares\n * @param extraOptions Optional LZ extra options (only used for async vaults)\n * @returns DepositResult or AsyncRequestResult depending on vault mode\n * @throws VaultPausedError if vault is paused\n * @throws CapacityFullError if vault is full\n */\nexport async function smartDeposit(\n signer: Signer,\n provider: Provider,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n extraOptions: string = \"0x\"\n): Promise<DepositResult | AsyncRequestResult> {\n const vault = addresses.vault;\n const status = await getVaultStatus(provider, vault);\n\n if (status.mode === \"paused\") {\n throw new VaultPausedError(vault);\n }\n if (status.mode === \"full\") {\n throw new CapacityFullError(vault);\n }\n\n if (status.recommendedDepositFlow === \"depositAsync\") {\n const lzFee = await quoteLzFee(provider, vault, extraOptions);\n return depositAsync(signer, addresses, assets, receiver, lzFee, extraOptions);\n }\n\n // local or cross-chain-oracle\n return depositSimple(signer, addresses, assets, receiver);\n}\n","/**\n * Vault topology helpers for the MoreVaults ethers.js v6 SDK.\n *\n * Resolves the cross-chain hub/spoke structure of a vault using the\n * MoreVaults OmniFactory contract (same address on every supported chain via CREATE3).\n */\n\nimport { Contract } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { EID_TO_CHAIN_ID, CHAIN_IDS, createChainProvider } from \"./chains\";\n\n// MoreVaults OMNI factory — same address on every supported chain (CREATE3)\nexport const OMNI_FACTORY_ADDRESS = \"0x7bDB8B17604b03125eFAED33cA0c55FBf856BB0C\";\n\nconst FACTORY_ABI = [\n \"function localEid() view returns (uint32)\",\n \"function isCrossChainVault(uint32 __eid, address _vault) view returns (bool)\",\n \"function hubToSpokes(uint32 __eid, address _hubVault) view returns (uint32[] eids, address[] vaults)\",\n \"function spokeToHub(uint32 __eid, address _spokeVault) view returns (uint32 eid, address vault)\",\n] as const;\n\nexport interface VaultTopology {\n /**\n * Role of this vault on the chain you queried:\n * - 'hub' → this chain holds the TVL, users deposit here\n * - 'spoke' → this chain is a yield deployment; deposits go to the hub\n * - 'local' → single-chain vault, no cross-chain setup\n */\n role: \"hub\" | \"spoke\" | \"local\";\n\n /** Chain ID where the hub lives. Same as the queried chain when role='hub'. */\n hubChainId: number;\n\n /**\n * All spoke chain IDs registered under this hub.\n * Empty when role='local'.\n * Since vaults are CREATE3-deployed, the vault address is the same on all chains.\n */\n spokeChainIds: number[];\n}\n\n/** All mainnet chain IDs where the OMNI_FACTORY is deployed */\nconst DISCOVERY_CHAIN_IDS = Object.values(CHAIN_IDS).filter(\n (id) => id !== 545, // exclude testnet\n) as number[];\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve the cross-chain topology of a vault: hub chain + all spoke chains.\n *\n * Works for hub vaults, spoke vaults, and local (single-chain) vaults.\n * Because MoreVaults uses CREATE3, the vault address is identical on every chain —\n * only the chain IDs differ.\n *\n * @param provider Connected to the chain you want to inspect\n * @param vault Vault address (same on all chains)\n * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)\n *\n * @example\n * // Querying from Base — will detect hub + Ethereum/Arbitrum spokes\n * const topo = await getVaultTopology(baseProvider, '0x8f740...')\n * // { role: 'hub', hubChainId: 8453, spokeChainIds: [1, 42161] }\n *\n * // Querying from Ethereum — same vault is a spoke there\n * const topo = await getVaultTopology(ethProvider, '0x8f740...')\n * // { role: 'spoke', hubChainId: 8453, spokeChainIds: [1, 42161] }\n */\nexport async function getVaultTopology(\n provider: Provider,\n vault: string,\n factoryAddress: string = OMNI_FACTORY_ADDRESS,\n): Promise<VaultTopology> {\n const factory = new Contract(factoryAddress, FACTORY_ABI, provider);\n\n // Get local EID from the factory on the queried chain\n const localEid: number = Number(await factory.localEid());\n\n // Check if this vault is a hub on the current chain\n const isHub: boolean = await factory.isCrossChainVault(localEid, vault);\n\n if (isHub) {\n // Hub: get all registered spokes\n const result = await factory.hubToSpokes(localEid, vault);\n const spokeEids: bigint[] = result[0];\n\n const localChainId = EID_TO_CHAIN_ID[localEid] ?? 0;\n const spokeChainIds = spokeEids\n .map((eid) => EID_TO_CHAIN_ID[Number(eid)])\n .filter((id): id is number => id !== undefined);\n\n return { role: \"hub\", hubChainId: localChainId, spokeChainIds };\n }\n\n // Check if this vault is a spoke on the current chain\n const spokeResult = await factory.spokeToHub(localEid, vault);\n const hubEid: number = Number(spokeResult[0]);\n const hubVault: string = spokeResult[1];\n\n if (hubEid !== 0 && hubVault !== \"0x0000000000000000000000000000000000000000\") {\n // Spoke: resolve hub chain\n const hubChainId = EID_TO_CHAIN_ID[hubEid] ?? 0;\n\n // We only have the current chain's provider — return what we know.\n // The hub's full spoke list requires a separate provider for the hub chain.\n const spokeChainIds: number[] = [];\n\n // If we happen to know the local chain mapping, include it as a spoke\n const localChainId = EID_TO_CHAIN_ID[localEid];\n if (localChainId !== undefined) spokeChainIds.push(localChainId);\n\n return { role: \"spoke\", hubChainId, spokeChainIds };\n }\n\n // Local vault — no cross-chain setup\n const localChainId = EID_TO_CHAIN_ID[localEid] ?? 0;\n return { role: \"local\", hubChainId: localChainId, spokeChainIds: [] };\n}\n\n/**\n * Resolve the FULL topology of a vault by querying the hub chain directly.\n *\n * Provide a provider connected to the hub chain for complete spoke data.\n * If you don't know which chain is the hub, call `getVaultTopology` first\n * from any chain and use the returned `hubChainId` to create the hub provider.\n *\n * @param hubChainProvider Provider connected to the hub chain\n * @param vault Vault address\n * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)\n */\nexport async function getFullVaultTopology(\n hubChainProvider: Provider,\n vault: string,\n factoryAddress: string = OMNI_FACTORY_ADDRESS,\n): Promise<VaultTopology> {\n const topo = await getVaultTopology(hubChainProvider, vault, factoryAddress);\n if (topo.role !== \"hub\") {\n throw new Error(\n `getFullVaultTopology: provider must be connected to the hub chain (${topo.hubChainId}), ` +\n `but got role=\"${topo.role}\". Connect to chainId ${topo.hubChainId} instead.`,\n );\n }\n return topo;\n}\n\n/**\n * Discover a vault's topology across all supported chains.\n *\n * Unlike `getVaultTopology` (which queries a single chain), this function\n * automatically iterates all supported chains when the initial query returns\n * `role: \"local\"`. This handles the case where the caller doesn't know which\n * chain the vault is deployed on, or when no provider is connected.\n *\n * If a `provider` is provided, it's tried first. If that returns \"local\",\n * every other supported chain is probed via public RPCs.\n * If no `provider` is provided, all chains are probed.\n *\n * Once a hub is found, `getFullVaultTopology` is called to get the complete\n * spoke list.\n *\n * @param vault Vault address (same on all chains via CREATE3)\n * @param provider Optional — provider for the \"preferred\" chain to try first\n * @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)\n *\n * @example\n * // No wallet connected — discovers that 0x8f74... is hub on Base\n * const topo = await discoverVaultTopology('0x8f740...')\n * // { role: 'hub', hubChainId: 8453, spokeChainIds: [1, 42161] }\n */\nexport async function discoverVaultTopology(\n vault: string,\n provider?: Provider | null,\n factoryAddress: string = OMNI_FACTORY_ADDRESS,\n): Promise<VaultTopology> {\n // 1. Try the provided provider first (fast path — avoids extra RPC calls)\n let triedChainId: number | undefined;\n if (provider) {\n try {\n const topo = await getVaultTopology(provider, vault, factoryAddress);\n if (topo.role !== \"local\") {\n // Found hub or spoke — if spoke, resolve full topology from hub\n if (topo.role === \"spoke\") {\n const hubProvider = createChainProvider(topo.hubChainId);\n if (hubProvider) {\n try {\n return await getFullVaultTopology(hubProvider, vault, factoryAddress);\n } catch { /* fall through to return partial */ }\n }\n }\n return topo;\n }\n // Determine which chainId we just tried\n const network = await provider.getNetwork();\n triedChainId = Number(network.chainId);\n } catch { /* provider failed — continue with discovery */ }\n }\n\n // 2. Iterate all supported chains\n for (const chainId of DISCOVERY_CHAIN_IDS) {\n if (chainId === triedChainId) continue;\n const chainProvider = createChainProvider(chainId);\n if (!chainProvider) continue;\n\n try {\n const topo = await getVaultTopology(chainProvider, vault, factoryAddress);\n if (topo.role === \"hub\") return topo;\n if (topo.role === \"spoke\") {\n // Found spoke — get full topology from hub\n const hubProvider = createChainProvider(topo.hubChainId);\n if (hubProvider) {\n try {\n return await getFullVaultTopology(hubProvider, vault, factoryAddress);\n } catch { return topo; }\n }\n return topo;\n }\n } catch { /* this chain doesn't have the factory or vault — skip */ }\n }\n\n // 3. Not found on any chain — return local with chainId 0\n return { role: \"local\", hubChainId: 0, spokeChainIds: [] };\n}\n\n/**\n * Check if a wallet is connected to the hub chain for a given vault.\n * Useful for showing a \"Switch to Base\" prompt before deposit.\n *\n * @param currentChainId Chain ID the wallet is currently connected to\n * @param topology Result of getVaultTopology\n */\nexport function isOnHubChain(currentChainId: number, topology: VaultTopology): boolean {\n return currentChainId === topology.hubChainId;\n}\n\n/**\n * Get all chain IDs where this vault is deployed (hub + all spokes).\n */\nexport function getAllVaultChainIds(topology: VaultTopology): number[] {\n return [topology.hubChainId, ...topology.spokeChainIds];\n}\n","import { Contract, AbiCoder, zeroPadValue, Signer, Provider, ZeroAddress } from \"ethers\";\nimport {\n VAULT_ABI,\n BRIDGE_ABI,\n ERC20_ABI,\n OFT_ABI,\n} from \"./abis\";\nimport {\n VaultAddresses,\n RedeemResult,\n AsyncRequestResult,\n ActionType,\n} from \"./types\";\nimport type { ContractTransactionReceipt } from \"ethers\";\nimport { preflightAsync, preflightRedeemLiquidity } from \"./preflight\";\nimport { EscrowNotConfiguredError } from \"./errors\";\nimport { validateWalletChain } from \"./chainValidation\";\nimport { getVaultStatus, quoteLzFee, detectStargateOft } from \"./utils\";\nimport { CHAIN_ID_TO_EID, OFT_ROUTES, createChainProvider } from \"./chains\";\nimport { OMNI_FACTORY_ADDRESS } from \"./topology\";\n\n/**\n * Ensure `spender` has at least `amount` allowance from `owner`.\n */\nasync function ensureAllowance(\n signer: Signer,\n token: string,\n spender: string,\n amount: bigint\n): Promise<void> {\n const owner = await signer.getAddress();\n const erc20 = new Contract(token, ERC20_ABI, signer);\n const current: bigint = await erc20.allowance(owner, spender);\n if (current < amount) {\n const tx = await erc20.approve(spender, amount);\n await tx.wait();\n }\n}\n\n// ---------------------------------------------------------------------------\n// R1 -- Simple redeem\n// ---------------------------------------------------------------------------\n\n/**\n * Redeem `shares` for underlying assets.\n *\n * TXs: 1 redeem.\n * Pre-condition: if withdrawal queue is enabled, `requestRedeem` must have\n * been called and the timelock must have elapsed.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param shares - Number of shares to redeem.\n * @param receiver - Address that will receive the underlying assets.\n * @param owner - Address that owns the shares.\n * @returns Assets received and the transaction receipt.\n */\nexport async function redeemShares(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string\n): Promise<RedeemResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n\n // Static call to get the return value (assets) before broadcasting\n const assets: bigint = await vault.redeem.staticCall(shares, receiver, owner);\n\n const tx = await vault.redeem(shares, receiver, owner);\n const receipt = await tx.wait();\n\n return { receipt, assets };\n}\n\n// ---------------------------------------------------------------------------\n// R2 -- Simple withdraw\n// ---------------------------------------------------------------------------\n\n/**\n * Withdraw exact `assets` amount of underlying tokens by burning shares.\n *\n * TXs: 1 withdraw.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param assets - Exact amount of underlying tokens to withdraw.\n * @param receiver - Address that will receive the tokens.\n * @param owner - Address that owns the shares.\n * @returns Assets received and the transaction receipt.\n */\nexport async function withdrawAssets(\n signer: Signer,\n addresses: VaultAddresses,\n assets: bigint,\n receiver: string,\n owner: string\n): Promise<RedeemResult> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault.withdraw(assets, receiver, owner);\n const receipt = await tx.wait();\n\n return { receipt, assets };\n}\n\n// ---------------------------------------------------------------------------\n// R3 -- Queue redeem, no timelock (2 TXs)\n// ---------------------------------------------------------------------------\n\n/**\n * Submit a withdrawal queue request for `shares`.\n *\n * TXs: 1 requestRedeem.\n * After this call and once any timelock elapses, call `redeemShares()` to\n * complete the withdrawal.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Vault addresses. Only `vault` is used.\n * @param shares - Number of shares to queue for redemption.\n * @param owner - Address on whose behalf to request.\n * @returns Transaction receipt.\n */\nexport async function requestRedeem(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n owner: string\n): Promise<{ receipt: ContractTransactionReceipt }> {\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n const vault = new Contract(addresses.vault, VAULT_ABI, signer);\n const tx = await vault.requestRedeem(shares, owner);\n const receipt = await tx.wait();\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// R4 -- Queue redeem with timelock (helper to check status)\n// ---------------------------------------------------------------------------\n\n/**\n * Get the current withdrawal request for an owner.\n * Returns null if no pending request exists.\n *\n * @param provider - JSON-RPC provider.\n * @param vault - Vault (diamond) address.\n * @param owner - Address of the shares owner.\n * @returns The request details or null.\n */\nexport async function getWithdrawalRequest(\n provider: Provider,\n vault: string,\n owner: string\n): Promise<{ shares: bigint; timelockEndsAt: bigint } | null> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const [shares, timelockEndsAt]: [bigint, bigint] =\n await vaultContract.getWithdrawalRequest(owner);\n\n if (shares === 0n) {\n return null;\n }\n\n return { shares, timelockEndsAt };\n}\n\n// ---------------------------------------------------------------------------\n// R5 -- Cross-chain oracle OFF, async redeem\n// ---------------------------------------------------------------------------\n\n/**\n * Initiate an asynchronous cross-chain redeem request.\n *\n * CRITICAL: shares are approved to the **escrow** address (vault share token).\n * amountLimit MUST be 0 for redeems.\n *\n * TXs: 1 approve to escrow for shares (if needed) + 1 initVaultActionRequest.\n * Wait: LayerZero cross-chain fulfillment.\n *\n * @param signer - Wallet holding the shares.\n * @param addresses - Must include `vault` and `escrow`.\n * @param shares - Number of shares to redeem.\n * @param receiver - Address that will receive the underlying assets.\n * @param owner - Address that owns the shares.\n * @param lzFee - Native fee for LayerZero message.\n * @param extraOptions - Optional LZ adapter parameters (bytes).\n * @returns The request GUID for tracking and the transaction receipt.\n */\nexport async function redeemAsync(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string,\n lzFee: bigint,\n extraOptions: string = \"0x\"\n): Promise<AsyncRequestResult> {\n const provider = signer.provider!;\n const escrow = addresses.escrow\n ?? await new Contract(addresses.vault, ['function getEscrow() view returns (address)'], provider).getEscrow()\n if (escrow === ZeroAddress) throw new EscrowNotConfiguredError(addresses.vault)\n\n // Validate wallet is on the correct chain (opt-in via hubChainId)\n await validateWalletChain(signer, addresses.hubChainId);\n\n // Pre-flight: validate async cross-chain setup before sending any transaction\n await preflightAsync(provider, addresses.vault, escrow);\n\n // Pre-flight: check hub has enough liquid assets — avoids wasting LZ fee on a guaranteed refund\n await preflightRedeemLiquidity(provider, addresses.vault, shares);\n\n // CRITICAL: approve ESCROW for shares (the vault token itself)\n await ensureAllowance(signer, addresses.vault, escrow, shares);\n\n const coder = AbiCoder.defaultAbiCoder();\n const actionCallData = coder.encode(\n [\"uint256\", \"address\", \"address\"],\n [shares, receiver, owner]\n );\n\n const bridge = new Contract(addresses.vault, BRIDGE_ABI, signer);\n\n // Static call first to capture the return value (guid) before broadcasting\n const guid: string = await bridge.initVaultActionRequest.staticCall(\n ActionType.REDEEM,\n actionCallData,\n 0,\n extraOptions,\n { value: lzFee }\n );\n\n const tx = await bridge.initVaultActionRequest(\n ActionType.REDEEM,\n actionCallData,\n 0, // amountLimit MUST be 0 for redeems\n extraOptions,\n { value: lzFee }\n );\n const receipt = await tx.wait();\n\n return { receipt, guid };\n}\n\n// ---------------------------------------------------------------------------\n// R6 -- Spoke -> Hub redeem (step 1: bridge shares to hub)\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge shares from a spoke chain to the hub chain (step 1 of 2).\n *\n * After the shares arrive on the hub chain, call `redeemShares()` on the\n * hub to complete the redemption.\n *\n * TXs: 1 approve (if needed) + 1 OFT.send().\n * Wait: LayerZero delivery (typically 1-5 minutes).\n *\n * @param signer - Wallet on the spoke chain holding shares.\n * @param shareOFT - OFTAdapter address for the share token on spoke.\n * @param hubChainEid - LayerZero endpoint ID for the hub chain (e.g. 30336 for Flow EVM).\n * @param shares - Number of shares to bridge.\n * @param receiver - Address on hub chain that will receive the shares.\n * @param lzFee - Native fee for LayerZero message.\n * @returns Transaction receipt.\n */\nexport async function bridgeSharesToHub(\n signer: Signer,\n shareOFT: string,\n hubChainEid: number,\n shares: bigint,\n receiver: string,\n lzFee: bigint\n): Promise<{ receipt: ContractTransactionReceipt }> {\n await ensureAllowance(signer, shareOFT, shareOFT, shares);\n\n const oft = new Contract(shareOFT, OFT_ABI, signer);\n const refundAddress = await signer.getAddress();\n const toBytes32 = zeroPadValue(receiver, 32);\n\n const sendParam = {\n dstEid: hubChainEid,\n to: toBytes32,\n amountLD: shares,\n minAmountLD: shares, // no slippage on share bridging\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// Smart redeem -- auto-detect vault type\n// ---------------------------------------------------------------------------\n\n/**\n * Smart redeem — auto-selects the correct flow based on vault configuration.\n *\n * Detects the vault mode and dispatches to:\n * - Sync vaults (local / cross-chain-oracle): `redeemShares`\n * - Async vaults (cross-chain, oracle OFF): `redeemAsync` (quotes LZ fee automatically)\n *\n * @param signer Wallet signer with account attached\n * @param addresses Vault address set (`escrow` required for async vaults)\n * @param shares Amount of shares to redeem\n * @param receiver Address that will receive the underlying assets\n * @param owner Owner of the shares being redeemed\n * @param extraOptions Optional LZ extra options (only used for async vaults)\n * @returns RedeemResult or AsyncRequestResult depending on vault mode\n */\nexport async function smartRedeem(\n signer: Signer,\n addresses: VaultAddresses,\n shares: bigint,\n receiver: string,\n owner: string,\n extraOptions: string = \"0x\"\n): Promise<RedeemResult | AsyncRequestResult> {\n const provider = signer.provider!;\n const vault = addresses.vault;\n const status = await getVaultStatus(provider, vault);\n\n if (status.mode === \"paused\") {\n throw new Error(`[MoreVaults] Vault ${vault} is paused. Cannot redeem.`);\n }\n\n if (status.recommendedDepositFlow === \"depositAsync\") {\n // Async vault — use redeemAsync\n const lzFee = await quoteLzFee(provider, vault, extraOptions);\n return redeemAsync(signer, addresses, shares, receiver, owner, lzFee, extraOptions);\n }\n\n // Sync vault — direct redeem\n return redeemShares(signer, addresses, shares, receiver, owner);\n}\n\n// ---------------------------------------------------------------------------\n// R7 -- Bridge assets from hub back to spoke\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge underlying assets from hub back to spoke chain via OFT.\n *\n * Step 3 of the full spoke redeem flow:\n * 1. bridgeSharesToHub() — shares spoke->hub\n * 2. smartRedeem() — redeem on hub\n * 3. bridgeAssetsToSpoke() — assets hub->spoke\n *\n * @param signer Wallet signer on the HUB chain\n * @param assetOFT OFT address for the underlying asset on hub\n * @param spokeChainEid LayerZero EID for the spoke (destination) chain\n * @param amount Amount of underlying assets to bridge\n * @param receiver Receiver address on the spoke chain\n * @param lzFee OFT send fee (quote via OFT.quoteSend)\n * @param isStargate Whether this is a Stargate OFT (uses TAXI mode)\n * @returns Transaction receipt\n */\nexport async function bridgeAssetsToSpoke(\n signer: Signer,\n assetOFT: string,\n spokeChainEid: number,\n amount: bigint,\n receiver: string,\n lzFee: bigint,\n isStargate: boolean = true\n): Promise<{ receipt: ContractTransactionReceipt }> {\n const oft = new Contract(assetOFT, OFT_ABI, signer);\n\n // Read underlying token and approve\n const token: string = await oft.token();\n if (token.toLowerCase() !== assetOFT.toLowerCase()) {\n await ensureAllowance(signer, token, assetOFT, amount);\n } else {\n await ensureAllowance(signer, assetOFT, assetOFT, amount);\n }\n\n const refundAddress = await signer.getAddress();\n const toBytes32 = zeroPadValue(receiver, 32);\n\n const sendParam = {\n dstEid: spokeChainEid,\n to: toBytes32,\n amountLD: amount,\n minAmountLD: amount * 99n / 100n, // 1% slippage for Stargate\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: isStargate ? \"0x01\" : \"0x\",\n };\n\n const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };\n\n const tx = await oft.send(sendParam, msgFee, refundAddress, {\n value: lzFee,\n });\n const receipt = await tx.wait();\n\n return { receipt };\n}\n\n// ---------------------------------------------------------------------------\n// Spoke redeem helpers\n// ---------------------------------------------------------------------------\n\n/** Minimal ABIs used only within redeemFlows */\nconst FACTORY_COMPOSER_ABI_RF = [\n \"function vaultComposer(address _vault) view returns (address)\",\n] as const;\n\nconst REDEEM_COMPOSER_ABI = [\n \"function SHARE_OFT() view returns (address)\",\n] as const;\n\nconst OFT_PEERS_ABI_RF = [\n \"function peers(uint32 eid) view returns (bytes32)\",\n] as const;\n\nexport interface SpokeRedeemRoute {\n /** Hub chain ID */\n hubChainId: number\n /** Spoke chain ID */\n spokeChainId: number\n /** LZ EID for the hub */\n hubEid: number\n /** LZ EID for the spoke */\n spokeEid: number\n /** Vault underlying asset address on hub */\n hubAsset: string\n /** SHARE_OFT on spoke chain */\n spokeShareOft: string\n /** Asset OFT on hub for bridging back */\n hubAssetOft: string\n /** Underlying asset address on spoke chain */\n spokeAsset: string\n /** Whether the asset OFT is a Stargate pool */\n isStargate: boolean\n /** OFT route symbol (e.g. 'stgUSDC') */\n symbol: string\n}\n\n/**\n * Quote the LZ fee for bridging shares from spoke to hub via SHARE_OFT.\n *\n * IMPORTANT: `amountLD` must be in SHARE_OFT native decimals (e.g. 18),\n * NOT vault decimals (e.g. 8). Use the raw `SHARE_OFT.balanceOf(user)` value.\n *\n * @param spokeProvider Read-only provider on the SPOKE chain\n * @param shareOFT SHARE_OFT address on the spoke chain\n * @param hubChainEid LayerZero Endpoint ID for the hub chain\n * @param amountLD Shares in SHARE_OFT native decimals (raw balanceOf)\n * @param receiver Receiver address on the hub chain\n * @returns LZ native fee in wei\n */\nexport async function quoteShareBridgeFee(\n spokeProvider: Provider,\n shareOFT: string,\n hubChainEid: number,\n amountLD: bigint,\n receiver: string,\n): Promise<bigint> {\n const toBytes32 = zeroPadValue(receiver, 32);\n const sendParam = {\n dstEid: hubChainEid,\n to: toBytes32,\n amountLD,\n minAmountLD: amountLD,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: \"0x\",\n };\n\n const oft = new Contract(shareOFT, OFT_ABI, spokeProvider);\n const fee = await oft.quoteSend(sendParam, false);\n return fee.nativeFee as bigint;\n}\n\n/**\n * Resolve all addresses needed for a full spoke→hub→spoke redeem flow.\n *\n * @param hubProvider Read-only provider on the HUB chain\n * @param vault Vault address\n * @param hubChainId Hub chain ID\n * @param spokeChainId Spoke chain ID where user has shares\n * @returns All addresses needed for bridgeSharesToHub + redeemShares + bridgeAssetsToSpoke\n */\nexport async function resolveRedeemAddresses(\n hubProvider: Provider,\n vault: string,\n hubChainId: number,\n spokeChainId: number,\n): Promise<SpokeRedeemRoute> {\n const hubEid = CHAIN_ID_TO_EID[hubChainId];\n const spokeEid = CHAIN_ID_TO_EID[spokeChainId];\n if (!hubEid || !spokeEid) {\n throw new Error(`No LZ EID for chainId ${!hubEid ? hubChainId : spokeChainId}`);\n }\n\n const vaultContract = new Contract(vault, VAULT_ABI, hubProvider);\n const factory = new Contract(OMNI_FACTORY_ADDRESS, FACTORY_COMPOSER_ABI_RF, hubProvider);\n const [hubAsset, composerAddress]: [string, string] = await Promise.all([\n vaultContract.asset(),\n factory.vaultComposer(vault),\n ]);\n\n if (composerAddress === ZeroAddress) {\n throw new Error(`[MoreVaults] No composer registered for vault ${vault} on hub chain ${hubChainId}`);\n }\n\n const composer = new Contract(composerAddress, REDEEM_COMPOSER_ABI, hubProvider);\n const hubShareOft: string = await composer.SHARE_OFT();\n\n const hubShareOftContract = new Contract(hubShareOft, OFT_PEERS_ABI_RF, hubProvider);\n const spokeShareOftBytes32: string = await hubShareOftContract.peers(spokeEid);\n\n // Convert bytes32 to address (last 20 bytes = last 40 hex chars)\n const spokeShareOft = `0x${spokeShareOftBytes32.slice(-40)}`;\n\n let hubAssetOft: string | null = null;\n let spokeAsset: string | null = null;\n let symbol = '';\n\n for (const [sym, chainMap] of Object.entries(OFT_ROUTES)) {\n const hubEntry = (chainMap as Record<number, { oft: string; token: string }>)[hubChainId];\n const spokeEntry = (chainMap as Record<number, { oft: string; token: string }>)[spokeChainId];\n if (!hubEntry || !spokeEntry) continue;\n\n if (hubEntry.token.toLowerCase() === hubAsset.toLowerCase()) {\n hubAssetOft = hubEntry.oft;\n spokeAsset = spokeEntry.token;\n symbol = sym;\n break;\n }\n }\n\n if (!hubAssetOft || !spokeAsset) {\n throw new Error(\n `[MoreVaults] No OFT route found for vault asset ${hubAsset} ` +\n `between hub chain ${hubChainId} and spoke chain ${spokeChainId}`,\n );\n }\n\n const isStargate = await detectStargateOft(hubProvider, hubAssetOft);\n\n return {\n hubChainId,\n spokeChainId,\n hubEid,\n spokeEid,\n hubAsset,\n spokeShareOft,\n hubAssetOft,\n spokeAsset,\n isStargate,\n symbol,\n };\n}\n","/**\n * User-facing helper functions for the MoreVaults ethers.js v6 SDK.\n *\n * All functions use Provider (read-only). None send transactions.\n */\n\nimport { Contract, Interface } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { BRIDGE_ABI, CONFIG_ABI, ERC20_ABI, VAULT_ABI, METADATA_ABI } from \"./abis\";\nimport type { CrossChainRequestInfo } from \"./types\";\nimport { getVaultStatus } from \"./utils\";\nimport type { VaultStatus } from \"./utils\";\nimport { CHAIN_ID_TO_EID, OFT_ROUTES, createChainProvider } from \"./chains\";\nimport { discoverVaultTopology, OMNI_FACTORY_ADDRESS } from \"./topology\";\n\n// Multicall3 — deployed at the same address on every EVM chain\nconst MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\nconst MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface UserPosition {\n /** Vault share balance */\n shares: bigint;\n /** convertToAssets(shares) — what they'd get if they redeemed now */\n estimatedAssets: bigint;\n /** Price of 1 full share in underlying (convertToAssets(10n ** decimals)) */\n sharePrice: bigint;\n /** Vault decimals (for display) */\n decimals: number;\n pendingWithdrawal: {\n shares: bigint;\n timelockEndsAt: bigint;\n /** block.timestamp >= timelockEndsAt (or timelockEndsAt === 0n) */\n canRedeemNow: boolean;\n } | null; // null if no pending withdrawal request\n}\n\n/**\n * Read the user's current position in the vault.\n *\n * @param provider Read-only provider for reads\n * @param vault Vault address (diamond proxy)\n * @param user User wallet address\n * @returns Full user position snapshot\n */\nexport async function getUserPosition(\n provider: Provider,\n vault: string,\n user: string\n): Promise<UserPosition> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // First batch: balance, decimals, withdrawal request — via Multicall3\n const b1Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"getWithdrawalRequest\", [user]) },\n ];\n\n const [b1Raw, block] = await Promise.all([\n mc.aggregate3.staticCall(b1Calls) as Promise<{ success: boolean; returnData: string }[]>,\n provider.getBlock(\"latest\"),\n ]);\n\n const shares = vaultIface.decodeFunctionResult(\"balanceOf\", b1Raw[0].returnData)[0] as bigint;\n const decimalsRaw = decimalsIface.decodeFunctionResult(\"decimals\", b1Raw[1].returnData)[0];\n const decimals = Number(decimalsRaw);\n const withdrawalResult = vaultIface.decodeFunctionResult(\"getWithdrawalRequest\", b1Raw[2].returnData);\n const withdrawalRequest: [bigint, bigint] = [withdrawalResult[0] as bigint, withdrawalResult[1] as bigint];\n\n const [withdrawShares, timelockEndsAt] = withdrawalRequest;\n\n // Second batch: convertToAssets calls (need shares and decimals from first batch)\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n const oneShare = 10n ** BigInt(decimals);\n const [estimatedAssets, sharePrice] = await Promise.all([\n shares === 0n\n ? Promise.resolve(0n)\n : (vaultContract.convertToAssets(shares) as Promise<bigint>),\n vaultContract.convertToAssets(oneShare) as Promise<bigint>,\n ]);\n\n const currentTimestamp = BigInt(block!.timestamp);\n\n const pendingWithdrawal =\n withdrawShares === 0n\n ? null\n : {\n shares: withdrawShares,\n timelockEndsAt,\n canRedeemNow:\n timelockEndsAt === 0n || currentTimestamp >= timelockEndsAt,\n };\n\n return {\n shares,\n estimatedAssets,\n sharePrice,\n decimals,\n pendingWithdrawal,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Preview how many shares a given asset amount would mint.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param assets Amount of underlying tokens to deposit\n * @returns Estimated shares to be minted\n */\nexport async function previewDeposit(\n provider: Provider,\n vault: string,\n assets: bigint\n): Promise<bigint> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n return vaultContract.previewDeposit(assets) as Promise<bigint>;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Preview how many underlying assets a given share amount would redeem.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param shares Amount of vault shares to redeem\n * @returns Estimated assets to be returned\n */\nexport async function previewRedeem(\n provider: Provider,\n vault: string,\n shares: bigint\n): Promise<bigint> {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n return vaultContract.previewRedeem(shares) as Promise<bigint>;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type DepositBlockReason =\n | \"paused\"\n | \"capacity-full\"\n | \"not-whitelisted\"\n | \"ok\";\n\nexport interface DepositEligibility {\n allowed: boolean;\n reason: DepositBlockReason;\n}\n\n/**\n * Check whether a user is eligible to deposit into the vault right now.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Eligibility result with reason\n */\nexport async function canDeposit(\n provider: Provider,\n vault: string,\n user: string\n): Promise<DepositEligibility> {\n const config = new Contract(vault, CONFIG_ABI, provider);\n\n const isPaused = await (config.paused() as Promise<boolean>);\n\n if (isPaused) {\n return { allowed: false, reason: \"paused\" };\n }\n\n // maxDeposit(user) can REVERT on vaults with whitelist/ACL\n let maxDepositAmount: bigint;\n try {\n maxDepositAmount = await (config.maxDeposit(user) as Promise<bigint>);\n } catch {\n // Revert means the vault has whitelist/ACL and this user is not approved\n return { allowed: false, reason: \"not-whitelisted\" };\n }\n\n if (maxDepositAmount === 0n) {\n return { allowed: false, reason: \"capacity-full\" };\n }\n return { allowed: true, reason: \"ok\" };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface VaultMetadata {\n name: string;\n symbol: string;\n decimals: number;\n underlying: string;\n underlyingSymbol: string;\n underlyingDecimals: number;\n}\n\n/**\n * Read display metadata for a vault and its underlying token.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns Vault and underlying token metadata\n */\nexport async function getVaultMetadata(\n provider: Provider,\n vault: string\n): Promise<VaultMetadata> {\n const MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\n const MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n ] as const;\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const metaIface = new Interface(METADATA_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n\n // Batch 1: name, symbol, decimals, asset — 1 eth_call via Multicall3\n const b1Calls = [\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"name\") },\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: vault, allowFailure: false, callData: metaIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const name = metaIface.decodeFunctionResult(\"name\", b1[0].returnData)[0] as string;\n const symbol = metaIface.decodeFunctionResult(\"symbol\", b1[1].returnData)[0] as string;\n const decimals = Number(metaIface.decodeFunctionResult(\"decimals\", b1[2].returnData)[0]);\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[3].returnData)[0] as string;\n\n // Batch 2: underlying symbol + decimals — 1 eth_call via Multicall3\n const b2Calls = [\n { target: underlying, allowFailure: false, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: underlying, allowFailure: false, callData: metaIface.encodeFunctionData(\"decimals\") },\n ];\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const underlyingSymbol = metaIface.decodeFunctionResult(\"symbol\", b2[0].returnData)[0] as string;\n const underlyingDecimals = Number(metaIface.decodeFunctionResult(\"decimals\", b2[1].returnData)[0]);\n\n return {\n name,\n symbol,\n decimals,\n underlying,\n underlyingSymbol,\n underlyingDecimals,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type AsyncRequestStatus =\n | \"pending\"\n | \"ready-to-execute\"\n | \"completed\"\n | \"refunded\";\n\nexport interface AsyncRequestStatusInfo {\n status: AsyncRequestStatus;\n /** Human-readable description */\n label: string;\n /** Shares minted or assets returned (0 if still pending) */\n result: bigint;\n}\n\n/**\n * Get the human-readable status of an async cross-chain request.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param guid Request GUID returned by depositAsync / mintAsync / redeemAsync\n * @returns Status info with label and result\n */\nexport async function getAsyncRequestStatusLabel(\n provider: Provider,\n vault: string,\n guid: string\n): Promise<AsyncRequestStatusInfo> {\n const bridge = new Contract(vault, BRIDGE_ABI, provider);\n\n const [info, finalizationResult]: [CrossChainRequestInfo, bigint] =\n await Promise.all([\n bridge.getRequestInfo(guid) as Promise<CrossChainRequestInfo>,\n bridge.getFinalizationResult(guid) as Promise<bigint>,\n ]);\n\n if (info.refunded) {\n return {\n status: \"refunded\",\n label: \"Request refunded — tokens returned to initiator\",\n result: 0n,\n };\n }\n if (info.finalized) {\n return {\n status: \"completed\",\n label: \"Completed\",\n result: finalizationResult,\n };\n }\n if (info.fulfilled) {\n return {\n status: \"ready-to-execute\",\n label: \"Oracle responded — ready to execute\",\n result: 0n,\n };\n }\n return {\n status: \"pending\",\n label: \"Waiting for cross-chain oracle response...\",\n result: 0n,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface UserBalances {\n /** Vault shares the user holds */\n shareBalance: bigint;\n /** Underlying token balance in wallet (for deposit input) */\n underlyingBalance: bigint;\n /** convertToAssets(shareBalance) — vault position value */\n estimatedAssets: bigint;\n}\n\n/**\n * Read the user's token balances relevant to a vault.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Share balance, underlying wallet balance, and estimated assets\n */\nexport async function getUserBalances(\n provider: Provider,\n vault: string,\n user: string\n): Promise<UserBalances> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n // Batch 1: shareBalance, decimals, underlying address\n const b1Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const shareBalance = vaultIface.decodeFunctionResult(\"balanceOf\", b1[0].returnData)[0] as bigint;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[2].returnData)[0] as string;\n\n // Batch 2: underlying wallet balance + estimated assets (skip convertToAssets if no shares)\n const [underlyingBalance, estimatedAssets] = await Promise.all([\n (new Contract(underlying, ERC20_ABI, provider).balanceOf(user) as Promise<bigint>),\n shareBalance === 0n\n ? Promise.resolve(0n)\n : (new Contract(vault, VAULT_ABI, provider).convertToAssets(shareBalance) as Promise<bigint>),\n ]);\n\n return {\n shareBalance,\n underlyingBalance,\n estimatedAssets,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MaxWithdrawable {\n /** How many shares can be redeemed right now */\n shares: bigint;\n /** How many underlying assets that corresponds to */\n assets: bigint;\n}\n\n/**\n * Calculate the maximum amount a user can withdraw from a vault right now.\n *\n * For hub vaults without oracle accounting, this is limited by hub liquidity.\n * For local and oracle vaults, all assets are immediately redeemable.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @param user User wallet address\n * @returns Maximum withdrawable shares and assets\n */\nexport async function getMaxWithdrawable(\n provider: Provider,\n vault: string,\n user: string\n): Promise<MaxWithdrawable> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const configIface = new Interface(CONFIG_ABI as unknown as string[]);\n const bridgeIface = new Interface(BRIDGE_ABI as unknown as string[]);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n\n // Batch 1: isHub, oraclesCrossChainAccounting, user share balance, underlying\n const b1Calls = [\n { target: vault, allowFailure: false, callData: configIface.encodeFunctionData(\"isHub\") },\n { target: vault, allowFailure: false, callData: bridgeIface.encodeFunctionData(\"oraclesCrossChainAccounting\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"asset\") },\n ];\n\n const b1: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b1Calls);\n\n const isHub = configIface.decodeFunctionResult(\"isHub\", b1[0].returnData)[0] as boolean;\n const oraclesEnabled = bridgeIface.decodeFunctionResult(\"oraclesCrossChainAccounting\", b1[1].returnData)[0] as boolean;\n const userShares = vaultIface.decodeFunctionResult(\"balanceOf\", b1[2].returnData)[0] as bigint;\n const underlying = vaultIface.decodeFunctionResult(\"asset\", b1[3].returnData)[0] as string;\n\n if (userShares === 0n) {\n return { shares: 0n, assets: 0n };\n }\n\n // Batch 2: estimated assets + hub liquid balance\n const b2Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"convertToAssets\", [userShares]) },\n { target: underlying, allowFailure: false, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [vault]) },\n ];\n\n const b2: { success: boolean; returnData: string }[] = await mc.aggregate3.staticCall(b2Calls);\n\n const estimatedAssets = vaultIface.decodeFunctionResult(\"convertToAssets\", b2[0].returnData)[0] as bigint;\n const hubLiquidBalance = erc20Iface.decodeFunctionResult(\"balanceOf\", b2[1].returnData)[0] as bigint;\n\n let maxAssets: bigint;\n if (isHub && !oraclesEnabled) {\n maxAssets = estimatedAssets < hubLiquidBalance ? estimatedAssets : hubLiquidBalance;\n } else {\n maxAssets = estimatedAssets;\n }\n\n let maxShares: bigint;\n if (maxAssets < estimatedAssets) {\n const vaultContract = new Contract(vault, VAULT_ABI, provider);\n maxShares = await (vaultContract.convertToShares(maxAssets) as Promise<bigint>);\n } else {\n maxShares = userShares;\n }\n\n return {\n shares: maxShares,\n assets: maxAssets,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type VaultSummary = VaultStatus & VaultMetadata;\n\n/**\n * Get a combined snapshot of vault status and metadata in one call.\n *\n * @param provider Read-only provider\n * @param vault Vault address\n * @returns Merged VaultStatus and VaultMetadata\n */\nexport async function getVaultSummary(\n provider: Provider,\n vault: string\n): Promise<VaultSummary> {\n const [status, metadata] = await Promise.all([\n getVaultStatus(provider, vault),\n getVaultMetadata(provider, vault),\n ]);\n return { ...status, ...metadata };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Minimal ABIs for SHARE_OFT discovery in getUserPositionMultiChain */\nconst FACTORY_COMPOSER_ABI_UH = [\n \"function vaultComposer(address _vault) view returns (address)\",\n] as const;\n\nconst COMPOSER_SHARE_OFT_ABI_UH = [\n \"function SHARE_OFT() view returns (address)\",\n] as const;\n\nconst OFT_PEERS_ABI_UH = [\n \"function peers(uint32 eid) view returns (bytes32)\",\n] as const;\n\nexport interface MultiChainUserPosition {\n /** Shares held directly on the hub vault (vault.balanceOf) */\n hubShares: bigint;\n /** Per-spoke SHARE_OFT balances normalized to vault decimals: { [chainId]: bigint } */\n spokeShares: Record<number, bigint>;\n /** Per-spoke SHARE_OFT raw balances in OFT native decimals: { [chainId]: bigint }\n * Use these for bridgeSharesToHub() and quoteShareBridgeFee() */\n rawSpokeShares: Record<number, bigint>;\n /** hubShares + sum of all spokeShares (in vault decimals) */\n totalShares: bigint;\n /** convertToAssets(totalShares) on the hub */\n estimatedAssets: bigint;\n /** Share price: convertToAssets(10^decimals) */\n sharePrice: bigint;\n /** Vault decimals */\n decimals: number;\n /** Pending async withdrawal request on hub, or null */\n pendingWithdrawal: {\n shares: bigint;\n timelockEndsAt: bigint;\n canRedeemNow: boolean;\n } | null;\n}\n\n/**\n * Read the user's position across all chains of an omni vault.\n *\n * Discovers topology automatically, reads hub shares + pending withdrawal,\n * then reads SHARE_OFT balances on each spoke chain in parallel.\n *\n * For local (single-chain) vaults, spokeShares will be empty and this\n * behaves identically to getUserPosition.\n *\n * @param vault Vault address (same on all chains via CREATE3)\n * @param user User wallet address\n * @returns Aggregated position across all chains\n */\nexport async function getUserPositionMultiChain(\n vault: string,\n user: string,\n): Promise<MultiChainUserPosition> {\n // Step 1: discover topology\n const topo = await discoverVaultTopology(vault);\n const hubProvider = createChainProvider(topo.hubChainId);\n if (!hubProvider) throw new Error(`No public RPC for hub chainId ${topo.hubChainId}`);\n\n // Step 2: read hub data (shares, decimals, withdrawal request)\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, hubProvider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const decimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n const b1Calls = [\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: vault, allowFailure: false, callData: decimalsIface.encodeFunctionData(\"decimals\") },\n { target: vault, allowFailure: false, callData: vaultIface.encodeFunctionData(\"getWithdrawalRequest\", [user]) },\n ];\n\n const [b1Raw, block] = await Promise.all([\n mc.aggregate3.staticCall(b1Calls) as Promise<{ success: boolean; returnData: string }[]>,\n hubProvider.getBlock(\"latest\"),\n ]);\n\n const hubShares = vaultIface.decodeFunctionResult(\"balanceOf\", b1Raw[0].returnData)[0] as bigint;\n const decimals = Number(decimalsIface.decodeFunctionResult(\"decimals\", b1Raw[1].returnData)[0]);\n const withdrawalResult = vaultIface.decodeFunctionResult(\"getWithdrawalRequest\", b1Raw[2].returnData);\n const withdrawShares = withdrawalResult[0] as bigint;\n const timelockEndsAt = withdrawalResult[1] as bigint;\n\n // Step 3: resolve SHARE_OFT addresses for spokes (if any)\n const spokeShares: Record<number, bigint> = {};\n const rawSpokeShares: Record<number, bigint> = {};\n\n if (topo.spokeChainIds.length > 0) {\n let hubShareOft: string | null = null;\n try {\n const factory = new Contract(OMNI_FACTORY_ADDRESS, FACTORY_COMPOSER_ABI_UH, hubProvider);\n const composerAddress: string = await factory.vaultComposer(vault);\n\n if (composerAddress !== \"0x0000000000000000000000000000000000000000\") {\n const composer = new Contract(composerAddress, COMPOSER_SHARE_OFT_ABI_UH, hubProvider);\n hubShareOft = await composer.SHARE_OFT();\n }\n } catch { /* no composer — skip spoke reads */ }\n\n if (hubShareOft) {\n const hubShareOftContract = new Contract(hubShareOft, OFT_PEERS_ABI_UH, hubProvider);\n\n const spokePromises = topo.spokeChainIds.map(async (spokeChainId) => {\n try {\n const spokeEid = CHAIN_ID_TO_EID[spokeChainId];\n if (!spokeEid) return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };\n\n const spokeOftBytes32: string = await hubShareOftContract.peers(spokeEid);\n const spokeOft = `0x${spokeOftBytes32.slice(-40)}`;\n\n if (spokeOft === \"0x0000000000000000000000000000000000000000\") {\n return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };\n }\n\n const spokeProvider = createChainProvider(spokeChainId);\n if (!spokeProvider) return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };\n\n // Read balance + decimals on spoke chain via Multicall3\n const spokeMc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, spokeProvider);\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n const spokeDecimalsIface = new Interface([\"function decimals() view returns (uint8)\"]);\n\n const spokeCalls = [\n { target: spokeOft, allowFailure: false, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [user]) },\n { target: spokeOft, allowFailure: false, callData: spokeDecimalsIface.encodeFunctionData(\"decimals\") },\n ];\n const spokeRaw: { success: boolean; returnData: string }[] =\n await spokeMc.aggregate3.staticCall(spokeCalls);\n\n const rawBalance = erc20Iface.decodeFunctionResult(\"balanceOf\", spokeRaw[0].returnData)[0] as bigint;\n const spokeOftDecimals = Number(spokeDecimalsIface.decodeFunctionResult(\"decimals\", spokeRaw[1].returnData)[0]);\n\n // Normalize to vault decimals\n let balance: bigint;\n if (spokeOftDecimals > decimals) {\n balance = rawBalance / (10n ** BigInt(spokeOftDecimals - decimals));\n } else if (spokeOftDecimals < decimals) {\n balance = rawBalance * (10n ** BigInt(decimals - spokeOftDecimals));\n } else {\n balance = rawBalance;\n }\n\n return { chainId: spokeChainId, balance, rawBalance };\n } catch {\n return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };\n }\n });\n\n const results = await Promise.all(spokePromises);\n for (const { chainId, balance, rawBalance } of results) {\n spokeShares[chainId] = balance;\n rawSpokeShares[chainId] = rawBalance;\n }\n }\n }\n\n // Step 4: compute totals\n const totalSpokeShares = Object.values(spokeShares).reduce((sum, b) => sum + b, 0n);\n const totalShares = hubShares + totalSpokeShares;\n\n const oneShare = 10n ** BigInt(decimals);\n const vaultContract = new Contract(vault, VAULT_ABI, hubProvider);\n const [estimatedAssets, sharePrice]: [bigint, bigint] = await Promise.all([\n totalShares === 0n\n ? Promise.resolve(0n)\n : (vaultContract.convertToAssets(totalShares) as Promise<bigint>),\n vaultContract.convertToAssets(oneShare) as Promise<bigint>,\n ]);\n\n // Step 5: pending withdrawal\n const currentTimestamp = BigInt(block?.timestamp ?? 0);\n const pendingWithdrawal = withdrawShares === 0n\n ? null\n : {\n shares: withdrawShares,\n timelockEndsAt,\n canRedeemNow: timelockEndsAt === 0n || currentTimestamp >= timelockEndsAt,\n };\n\n return {\n hubShares,\n spokeShares,\n rawSpokeShares,\n totalShares,\n estimatedAssets,\n sharePrice,\n decimals,\n pendingWithdrawal,\n };\n}\n","/**\n * Curator / vault-manager read helpers for the MoreVaults ethers.js v6 SDK.\n *\n * All functions are read-only (no wallet needed) and use Multicall3 for\n * batched RPC efficiency.\n */\n\nimport { Contract, Interface } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport {\n MULTICALL_ABI,\n CURATOR_CONFIG_ABI,\n VAULT_ANALYSIS_ABI,\n REGISTRY_ABI,\n METADATA_ABI,\n ERC20_ABI,\n VAULT_ABI,\n} from \"./abis\";\nimport type {\n CuratorVaultStatus,\n PendingAction,\n VaultAnalysis,\n AssetInfo,\n AssetBalance,\n VaultAssetBreakdown,\n} from \"./types\";\n\n// Multicall3 — deployed at the same address on every EVM chain\nconst MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\";\nconst MULTICALL3_ABI = [\n \"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)\",\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Read a comprehensive status snapshot for the curator dashboard.\n *\n * Fetches in one multicall batch:\n * curator, timeLockPeriod, getMaxSlippagePercent, getCurrentNonce,\n * getAvailableAssets, getCrossChainAccountingManager, paused\n *\n * @param provider Read-only provider (must be on the vault's chain)\n * @param vault Vault address (diamond proxy)\n * @returns CuratorVaultStatus snapshot\n */\nexport async function getCuratorVaultStatus(\n provider: Provider,\n vault: string\n): Promise<CuratorVaultStatus> {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const curatorConfigIface = new Interface(CURATOR_CONFIG_ABI as unknown as string[]);\n const multicallIface = new Interface(MULTICALL_ABI as unknown as string[]);\n\n const calls = [\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"curator\") },\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"timeLockPeriod\") },\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"getMaxSlippagePercent\") },\n { target: vault, allowFailure: false, callData: multicallIface.encodeFunctionData(\"getCurrentNonce\") },\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"getAvailableAssets\") },\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"getCrossChainAccountingManager\") },\n { target: vault, allowFailure: false, callData: curatorConfigIface.encodeFunctionData(\"paused\") },\n ];\n\n const results: { success: boolean; returnData: string }[] =\n await mc.aggregate3.staticCall(calls);\n\n const curator = curatorConfigIface.decodeFunctionResult(\"curator\", results[0].returnData)[0] as string;\n const timeLockPeriod = curatorConfigIface.decodeFunctionResult(\"timeLockPeriod\", results[1].returnData)[0] as bigint;\n const maxSlippagePercent = curatorConfigIface.decodeFunctionResult(\"getMaxSlippagePercent\", results[2].returnData)[0] as bigint;\n const currentNonce = multicallIface.decodeFunctionResult(\"getCurrentNonce\", results[3].returnData)[0] as bigint;\n const availableAssets = curatorConfigIface.decodeFunctionResult(\"getAvailableAssets\", results[4].returnData)[0] as string[];\n const lzAdapter = curatorConfigIface.decodeFunctionResult(\"getCrossChainAccountingManager\", results[5].returnData)[0] as string;\n const paused = curatorConfigIface.decodeFunctionResult(\"paused\", results[6].returnData)[0] as boolean;\n\n return {\n curator,\n timeLockPeriod,\n maxSlippagePercent,\n currentNonce,\n availableAssets,\n lzAdapter,\n paused,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Fetch pending actions for a specific nonce and resolve whether they are\n * executable (i.e. the timelock has expired).\n *\n * @param provider Read-only provider (must be on the vault's chain)\n * @param vault Vault address (diamond proxy)\n * @param nonce Action nonce to query\n * @returns PendingAction with isExecutable flag set\n */\nexport async function getPendingActions(\n provider: Provider,\n vault: string,\n nonce: bigint\n): Promise<PendingAction> {\n const multicallContract = new Contract(vault, MULTICALL_ABI, provider);\n\n const [result, block] = await Promise.all([\n multicallContract.getPendingActions(nonce) as Promise<[string[], bigint]>,\n provider.getBlock(\"latest\"),\n ]);\n\n const [actionsData, pendingUntil] = result;\n const currentTimestamp = BigInt(block!.timestamp);\n const isExecutable = pendingUntil > 0n && currentTimestamp >= pendingUntil;\n\n return {\n nonce,\n actionsData,\n pendingUntil,\n isExecutable,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Check whether a given address is the curator of the vault.\n *\n * @param provider Read-only provider (must be on the vault's chain)\n * @param vault Vault address (diamond proxy)\n * @param address Address to check\n * @returns true if address is the current curator\n */\nexport async function isCurator(\n provider: Provider,\n vault: string,\n address: string\n): Promise<boolean> {\n const config = new Contract(vault, CURATOR_CONFIG_ABI, provider);\n const curatorAddress = (await config.curator()) as string;\n return curatorAddress.toLowerCase() === address.toLowerCase();\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Full vault analysis — available assets with metadata, depositable assets, whitelist config.\n * Useful for curator dashboards to understand what the vault can do.\n *\n * @param provider Read-only provider (must be on the vault's chain)\n * @param vault Vault address (diamond proxy)\n * @returns VaultAnalysis snapshot\n */\nexport async function getVaultAnalysis(\n provider: Provider,\n vault: string\n): Promise<VaultAnalysis> {\n const analysisContract = new Contract(vault, VAULT_ANALYSIS_ABI, provider);\n\n // Batch 1: fetch asset lists, whitelist flag, and registry address in parallel\n const [availableRaw, depositableRaw, depositWhitelistEnabled, registryResult] =\n await Promise.all([\n analysisContract.getAvailableAssets() as Promise<string[]>,\n analysisContract.getDepositableAssets() as Promise<string[]>,\n analysisContract.isDepositWhitelistEnabled() as Promise<boolean>,\n (analysisContract.moreVaultsRegistry() as Promise<string>).catch(() => null),\n ]);\n\n const availableAddresses = availableRaw as string[];\n const depositableAddresses = depositableRaw as string[];\n\n // Deduplicated set of all asset addresses we need metadata for\n const allAddresses = Array.from(new Set([...availableAddresses, ...depositableAddresses]));\n\n // Batch 2: multicall for name/symbol/decimals on all unique assets\n const assetInfoMap = new Map<string, AssetInfo>();\n\n if (allAddresses.length > 0) {\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const metaIface = new Interface(METADATA_ABI as unknown as string[]);\n\n const metadataCalls = allAddresses.flatMap((addr) => [\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"name\") },\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"decimals\") },\n ]);\n\n const metadataResults: { success: boolean; returnData: string }[] =\n await mc.aggregate3.staticCall(metadataCalls);\n\n for (let i = 0; i < allAddresses.length; i++) {\n const addr = allAddresses[i];\n const nameRes = metadataResults[i * 3];\n const symbolRes = metadataResults[i * 3 + 1];\n const decimalsRes = metadataResults[i * 3 + 2];\n\n const name = nameRes.success ? (metaIface.decodeFunctionResult(\"name\", nameRes.returnData)[0] as string) : '';\n const symbol = symbolRes.success ? (metaIface.decodeFunctionResult(\"symbol\", symbolRes.returnData)[0] as string) : '';\n const decimals = decimalsRes.success ? (Number(metaIface.decodeFunctionResult(\"decimals\", decimalsRes.returnData)[0])) : 18;\n\n assetInfoMap.set(addr.toLowerCase(), { address: addr, name, symbol, decimals });\n }\n }\n\n const registryAddress = registryResult ? (registryResult as string) : null;\n\n return {\n availableAssets: availableAddresses.map((a) => assetInfoMap.get(a.toLowerCase())!),\n depositableAssets: depositableAddresses.map((a) => assetInfoMap.get(a.toLowerCase())!),\n depositWhitelistEnabled: depositWhitelistEnabled as boolean,\n registryAddress,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if specific protocol addresses are whitelisted in the global registry.\n * Useful for curators to verify DEX routers before building swap calldata.\n *\n * @param provider Read-only provider (must be on the vault's chain)\n * @param vault Vault address (diamond proxy)\n * @param protocols Protocol addresses to check\n * @returns Record mapping address → whitelisted boolean\n */\nexport async function checkProtocolWhitelist(\n provider: Provider,\n vault: string,\n protocols: string[]\n): Promise<Record<string, boolean>> {\n const analysisContract = new Contract(vault, VAULT_ANALYSIS_ABI, provider);\n const registry = (await analysisContract.moreVaultsRegistry()) as string;\n\n if (protocols.length === 0) return {};\n\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const registryIface = new Interface(REGISTRY_ABI as unknown as string[]);\n\n const calls = protocols.map((protocol) => ({\n target: registry,\n allowFailure: true,\n callData: registryIface.encodeFunctionData(\"isWhitelisted\", [protocol]),\n }));\n\n const results: { success: boolean; returnData: string }[] =\n await mc.aggregate3.staticCall(calls);\n\n const out: Record<string, boolean> = {};\n for (let i = 0; i < protocols.length; i++) {\n const r = results[i];\n const whitelisted = r.success\n ? (registryIface.decodeFunctionResult(\"isWhitelisted\", r.returnData)[0] as boolean)\n : false;\n out[protocols[i].toLowerCase()] = whitelisted;\n }\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Get the vault's per-asset balance breakdown on the hub chain.\n *\n * Returns the balance of every available asset held by the vault, plus\n * totalAssets and totalSupply for context. Useful for portfolio views\n * that need to show individual holdings rather than a single USD-denominated total.\n *\n * @param provider Read-only provider (must be on the vault's hub chain)\n * @param vault Vault address (diamond proxy)\n * @returns VaultAssetBreakdown with per-asset balances\n */\nexport async function getVaultAssetBreakdown(\n provider: Provider,\n vault: string\n): Promise<VaultAssetBreakdown> {\n // Step 1: get available assets list\n const analysisContract = new Contract(vault, VAULT_ANALYSIS_ABI, provider);\n const availableRaw = (await analysisContract.getAvailableAssets()) as string[];\n const addresses = availableRaw as string[];\n\n // Step 2: multicall — balanceOf + metadata for each asset + totalAssets + totalSupply + vault decimals\n const mc = new Contract(MULTICALL3_ADDRESS, MULTICALL3_ABI, provider);\n const vaultIface = new Interface(VAULT_ABI as unknown as string[]);\n const metaIface = new Interface(METADATA_ABI as unknown as string[]);\n const erc20Iface = new Interface(ERC20_ABI as unknown as string[]);\n\n const perAssetCalls = addresses.flatMap((addr) => [\n { target: addr, allowFailure: true, callData: erc20Iface.encodeFunctionData(\"balanceOf\", [vault]) },\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"name\") },\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"symbol\") },\n { target: addr, allowFailure: true, callData: metaIface.encodeFunctionData(\"decimals\") },\n ]);\n\n const totalCalls = [\n ...perAssetCalls,\n { target: vault, allowFailure: true, callData: vaultIface.encodeFunctionData(\"totalAssets\") },\n { target: vault, allowFailure: true, callData: vaultIface.encodeFunctionData(\"totalSupply\") },\n { target: vault, allowFailure: true, callData: metaIface.encodeFunctionData(\"decimals\") },\n ];\n\n const results: { success: boolean; returnData: string }[] =\n await mc.aggregate3.staticCall(totalCalls);\n\n const perAssetFields = 4; // balanceOf, name, symbol, decimals\n const assets: AssetBalance[] = addresses.map((addr, i) => {\n const base = i * perAssetFields;\n const balance = results[base].success ? (erc20Iface.decodeFunctionResult(\"balanceOf\", results[base].returnData)[0] as bigint) : 0n;\n const name = results[base + 1].success ? (metaIface.decodeFunctionResult(\"name\", results[base + 1].returnData)[0] as string) : '';\n const symbol = results[base + 2].success ? (metaIface.decodeFunctionResult(\"symbol\", results[base + 2].returnData)[0] as string) : '';\n const decimals = results[base + 3].success ? (Number(metaIface.decodeFunctionResult(\"decimals\", results[base + 3].returnData)[0])) : 18;\n\n return { address: addr, name, symbol, decimals, balance };\n });\n\n const totalsBase = addresses.length * perAssetFields;\n const totalAssets = results[totalsBase].success ? (vaultIface.decodeFunctionResult(\"totalAssets\", results[totalsBase].returnData)[0] as bigint) : 0n;\n const totalSupply = results[totalsBase + 1].success ? (vaultIface.decodeFunctionResult(\"totalSupply\", results[totalsBase + 1].returnData)[0] as bigint) : 0n;\n const underlyingDecimals = results[totalsBase + 2].success ? (Number(metaIface.decodeFunctionResult(\"decimals\", results[totalsBase + 2].returnData)[0])) : 6;\n\n return { assets, totalAssets, totalSupply, underlyingDecimals };\n}\n","/**\n * Curator MulticallFacet write operations for the MoreVaults ethers.js v6 SDK.\n *\n * Provides typed helpers to submit, execute, and veto curator action batches\n * on any MoreVaults diamond that has the MulticallFacet installed.\n *\n * @module curatorMulticall\n */\n\nimport { Contract, Interface } from \"ethers\";\nimport type { Signer, ContractTransactionReceipt } from \"ethers\";\nimport {\n MULTICALL_ABI,\n DEX_ABI,\n ERC7540_FACET_ABI,\n ERC4626_FACET_ABI,\n} from \"./abis\";\nimport type { CuratorAction, SubmitActionsResult } from \"./types\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Encoding helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Encode a single typed CuratorAction into raw calldata bytes suitable for\n * passing into `submitActions(bytes[] actionsData)`.\n *\n * The encoded bytes are the full ABI-encoded function call (4-byte selector +\n * arguments) targeting the vault diamond itself — the MulticallFacet will\n * call `address(this).call(actionsData[i])` for each entry.\n *\n * @param action A discriminated-union CuratorAction describing what to do\n * @returns ABI-encoded calldata hex string\n */\nexport function encodeCuratorAction(action: CuratorAction): string {\n switch (action.type) {\n case 'swap': {\n const iface = new Interface(DEX_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"executeSwap\", [\n {\n targetContract: action.params.targetContract,\n tokenIn: action.params.tokenIn,\n tokenOut: action.params.tokenOut,\n maxAmountIn: action.params.maxAmountIn,\n minAmountOut: action.params.minAmountOut,\n swapCallData: action.params.swapCallData,\n },\n ]);\n }\n\n case 'batchSwap': {\n const iface = new Interface(DEX_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"executeBatchSwap\", [\n {\n swaps: action.params.swaps.map((s) => ({\n targetContract: s.targetContract,\n tokenIn: s.tokenIn,\n tokenOut: s.tokenOut,\n maxAmountIn: s.maxAmountIn,\n minAmountOut: s.minAmountOut,\n swapCallData: s.swapCallData,\n })),\n },\n ]);\n }\n\n case 'erc4626Deposit': {\n const iface = new Interface(ERC4626_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc4626Deposit\", [action.vault, action.assets]);\n }\n\n case 'erc4626Redeem': {\n const iface = new Interface(ERC4626_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc4626Redeem\", [action.vault, action.shares]);\n }\n\n case 'erc7540RequestDeposit': {\n const iface = new Interface(ERC7540_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc7540RequestDeposit\", [action.vault, action.assets]);\n }\n\n case 'erc7540Deposit': {\n const iface = new Interface(ERC7540_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc7540Deposit\", [action.vault, action.assets]);\n }\n\n case 'erc7540RequestRedeem': {\n const iface = new Interface(ERC7540_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc7540RequestRedeem\", [action.vault, action.shares]);\n }\n\n case 'erc7540Redeem': {\n const iface = new Interface(ERC7540_FACET_ABI as unknown as string[]);\n return iface.encodeFunctionData(\"erc7540Redeem\", [action.vault, action.shares]);\n }\n\n default: {\n // TypeScript exhaustiveness check — this branch is never reached at runtime\n const _exhaustive: never = action;\n throw new Error(`[MoreVaults] Unknown CuratorAction type: ${(_exhaustive as any).type}`);\n }\n }\n}\n\n/**\n * Encode an array of CuratorActions into a calldata array ready for\n * `submitActions`.\n *\n * @param actions Array of typed CuratorAction objects\n * @returns Array of ABI-encoded calldata hex strings\n */\nexport function buildCuratorBatch(actions: CuratorAction[]): string[] {\n return actions.map(encodeCuratorAction);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Write operations\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Submit a batch of curator actions to the vault's MulticallFacet.\n *\n * When `timeLockPeriod == 0` the contract immediately executes the actions\n * inside `submitActions` itself. When a timelock is configured the actions\n * are queued and must be executed later with `executeActions`.\n *\n * After the write succeeds, reads `getCurrentNonce` to determine which nonce\n * was assigned (nonce - 1 after the submit increments it).\n *\n * @param signer Signer with curator account attached\n * @param vault Vault address (diamond proxy)\n * @param actions Array of raw calldata bytes — use `buildCuratorBatch` to build\n * @returns Receipt and the nonce assigned to this batch\n */\nexport async function submitActions(\n signer: Signer,\n vault: string,\n actions: string[]\n): Promise<SubmitActionsResult> {\n const multicallContract = new Contract(vault, MULTICALL_ABI, signer);\n\n const tx = await multicallContract.submitActions(actions);\n const receipt: ContractTransactionReceipt = await tx.wait();\n\n // Read the nonce that was assigned: the contract increments actionNonce after storing,\n // so getCurrentNonce now returns (assignedNonce + 1). Subtract 1 to recover it.\n const nextNonce = (await multicallContract.getCurrentNonce()) as bigint;\n const nonce = nextNonce - 1n;\n\n return { receipt, nonce };\n}\n\n/**\n * Execute pending actions after their timelock period has expired.\n *\n * Can only be called when `block.timestamp >= pendingUntil`. The contract\n * reverts with `ActionsStillPending` if the timelock has not expired.\n *\n * @param signer Signer with curator account attached\n * @param vault Vault address (diamond proxy)\n * @param nonce The action batch nonce to execute\n * @returns Transaction receipt\n */\nexport async function executeActions(\n signer: Signer,\n vault: string,\n nonce: bigint\n): Promise<ContractTransactionReceipt> {\n const multicallContract = new Contract(vault, MULTICALL_ABI, signer);\n\n const tx = await multicallContract.executeActions(nonce);\n return tx.wait() as Promise<ContractTransactionReceipt>;\n}\n\n/**\n * Guardian-only: cancel (veto) one or more pending action batches.\n *\n * Deletes the pending actions from storage, preventing them from ever being\n * executed. Only the vault guardian can call this.\n *\n * @param signer Signer with guardian account attached\n * @param vault Vault address (diamond proxy)\n * @param nonces Array of action nonces to cancel\n * @returns Transaction receipt\n */\nexport async function vetoActions(\n signer: Signer,\n vault: string,\n nonces: bigint[]\n): Promise<ContractTransactionReceipt> {\n const multicallContract = new Contract(vault, MULTICALL_ABI, signer);\n\n const tx = await multicallContract.vetoActions(nonces);\n return tx.wait() as Promise<ContractTransactionReceipt>;\n}\n","/**\n * Curator swap helpers for Uniswap V3-compatible DEXes.\n *\n * Provides typed helpers to build CuratorAction objects and raw calldata for\n * Uniswap V3 exactInputSingle swaps, automatically resolving the correct router\n * and ABI variant (SwapRouter vs SwapRouter02) per chain.\n *\n * Supported chains and routers:\n * - Base (8453): SwapRouter02 0x2626... — NO deadline field\n * - Ethereum (1): SwapRouter 0xE592... — HAS deadline field\n * - Arbitrum (42161): SwapRouter 0xE592... — HAS deadline field\n * - Optimism (10): SwapRouter 0xE592... — HAS deadline field\n * - Flow EVM (747): FlowSwap V3 0xeEDC... — HAS deadline field\n *\n * @module curatorSwaps\n */\n\nimport { Interface } from \"ethers\";\nimport { UNISWAP_V3_ROUTERS } from \"./chains\";\nimport type { CuratorAction } from \"./types\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ABI constants\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Uniswap V3 SwapRouter exactInputSingle ABI (human-readable).\n * Used for: Ethereum (1), Arbitrum (42161), Optimism (10), Flow EVM (747).\n * Struct includes `deadline` field.\n */\nconst UNISWAP_V3_SWAP_ROUTER_ABI = [\n \"function exactInputSingle(tuple(address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)\",\n] as const;\n\n/**\n * Uniswap V3 SwapRouter02 exactInputSingle ABI (human-readable).\n * Used for: Base (8453).\n * Struct does NOT include `deadline` field — SwapRouter02 removed it.\n */\nconst UNISWAP_V3_SWAP_ROUTER02_ABI = [\n \"function exactInputSingle(tuple(address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)\",\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Chain variant detection\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Chains that use SwapRouter02 (no deadline in struct).\n * All other chains in UNISWAP_V3_ROUTERS use the original SwapRouter.\n */\nconst SWAP_ROUTER02_CHAINS = new Set([8453]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Calldata encoding\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Encode Uniswap V3 exactInputSingle calldata directly.\n * For curators who want raw calldata without the CuratorAction wrapper.\n *\n * Automatically selects the correct ABI variant (SwapRouter vs SwapRouter02)\n * based on the chainId. The deadline (for SwapRouter chains) is set to\n * `now + 20 minutes` to prevent stale transactions from executing.\n *\n * @param params.chainId EVM chain ID — must be present in UNISWAP_V3_ROUTERS\n * @param params.tokenIn Input token address\n * @param params.tokenOut Output token address\n * @param params.fee Pool fee tier: 100, 500, 3000, or 10000\n * @param params.amountIn Exact input amount (in tokenIn units)\n * @param params.minAmountOut Minimum acceptable output (slippage protection)\n * @param params.recipient Address to receive the output tokens (usually the vault)\n * @returns The router contract address and ABI-encoded calldata\n * @throws If no router is configured for the given chainId\n */\nexport function encodeUniswapV3SwapCalldata(params: {\n chainId: number;\n tokenIn: string;\n tokenOut: string;\n fee: number;\n amountIn: bigint;\n minAmountOut: bigint;\n recipient: string;\n}): { targetContract: string; swapCallData: string } {\n const { chainId, tokenIn, tokenOut, fee, amountIn, minAmountOut, recipient } = params;\n\n const router = UNISWAP_V3_ROUTERS[chainId];\n if (!router) {\n throw new Error(\n `[MoreVaults] No Uniswap V3 router configured for chainId ${chainId}. ` +\n `Supported chains: ${Object.keys(UNISWAP_V3_ROUTERS).join(', ')}`\n );\n }\n\n let swapCallData: string;\n\n if (SWAP_ROUTER02_CHAINS.has(chainId)) {\n // SwapRouter02 (Base) — no deadline field\n const iface = new Interface(UNISWAP_V3_SWAP_ROUTER02_ABI as unknown as string[]);\n swapCallData = iface.encodeFunctionData(\"exactInputSingle\", [\n {\n tokenIn,\n tokenOut,\n fee,\n recipient,\n amountIn,\n amountOutMinimum: minAmountOut,\n sqrtPriceLimitX96: 0n,\n },\n ]);\n } else {\n // Original SwapRouter (Eth/Arb/Op/Flow EVM) — has deadline field\n const deadline = BigInt(Math.floor(Date.now() / 1000) + 1200); // now + 20 minutes\n const iface = new Interface(UNISWAP_V3_SWAP_ROUTER_ABI as unknown as string[]);\n swapCallData = iface.encodeFunctionData(\"exactInputSingle\", [\n {\n tokenIn,\n tokenOut,\n fee,\n recipient,\n deadline,\n amountIn,\n amountOutMinimum: minAmountOut,\n sqrtPriceLimitX96: 0n,\n },\n ]);\n }\n\n return { targetContract: router, swapCallData };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CuratorAction builder\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Build a CuratorAction for a Uniswap V3 exactInputSingle swap.\n *\n * Automatically resolves the router address from UNISWAP_V3_ROUTERS and\n * selects the correct ABI struct (with or without deadline) based on chainId.\n *\n * The returned action is a `swap` variant ready to be passed to\n * `buildCuratorBatch` and then `submitActions`.\n *\n * @param params.chainId EVM chain ID — must be present in UNISWAP_V3_ROUTERS\n * @param params.tokenIn Input token address\n * @param params.tokenOut Output token address\n * @param params.fee Pool fee tier: 100, 500, 3000, or 10000\n * @param params.amountIn Exact input amount (in tokenIn units)\n * @param params.minAmountOut Minimum acceptable output (slippage protection)\n * @param params.recipient Address to receive output tokens (usually the vault)\n * @returns A typed CuratorAction ready for buildCuratorBatch\n * @throws If no router is configured for the given chainId\n *\n * @example\n * ```typescript\n * const action = buildUniswapV3Swap({\n * chainId: 8453,\n * tokenIn: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC\n * tokenOut: '0x4200000000000000000000000000000000000006', // WETH\n * fee: 500, // 0.05% pool\n * amountIn: 150_000n, // 0.15 USDC (6 decimals)\n * minAmountOut: 1n, // accept any amount (set properly in production)\n * recipient: VAULT,\n * })\n * const batch = buildCuratorBatch([action])\n * await submitActions(signer, vault, batch)\n * ```\n */\nexport function buildUniswapV3Swap(params: {\n chainId: number;\n tokenIn: string;\n tokenOut: string;\n fee: number;\n amountIn: bigint;\n minAmountOut: bigint;\n recipient: string;\n}): CuratorAction {\n const { targetContract, swapCallData } = encodeUniswapV3SwapCalldata(params);\n\n return {\n type: 'swap',\n params: {\n targetContract,\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n maxAmountIn: params.amountIn,\n minAmountOut: params.minAmountOut,\n swapCallData,\n },\n };\n}\n","/**\n * Vault distribution helpers for the MoreVaults ethers.js v6 SDK.\n *\n * Reads the cross-chain capital distribution of a vault: hub balance,\n * spoke balances, and aggregate totals.\n */\n\nimport type { Provider } from \"ethers\";\nimport { getVaultStatus } from \"./utils\";\nimport { getVaultTopology } from \"./topology\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SpokeBalance {\n chainId: number;\n totalAssets: bigint;\n /** false if the RPC call to this spoke failed */\n isReachable: boolean;\n}\n\nexport interface VaultDistribution {\n hubChainId: number;\n /** Underlying token balance idle on the hub (not deployed to strategies) */\n hubLiquidBalance: bigint;\n /** Hub totalAssets minus hubLiquidBalance (capital in Morpho, Aave, etc.) */\n hubStrategyBalance: bigint;\n /** Hub vault totalAssets() */\n hubTotalAssets: bigint;\n /** What the hub's accounting thinks is deployed on spokes */\n spokesDeployedBalance: bigint;\n /** Actual per-spoke balances read directly from each spoke chain */\n spokeBalances: SpokeBalance[];\n /** hubTotalAssets + sum of reachable spoke totalAssets */\n totalActual: bigint;\n oracleAccountingEnabled: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Read the full cross-chain capital distribution of a vault.\n *\n * Queries the hub for its status, then reads `totalAssets()` on each spoke\n * chain in parallel. Spoke calls are individually wrapped so a single\n * unreachable RPC never fails the entire call.\n *\n * @param hubProvider Provider connected to the hub chain\n * @param vault Vault address (same on all chains via CREATE3)\n * @param spokeProviders Map of chainId → Provider for each spoke chain\n *\n * @example\n * ```ts\n * const dist = await getVaultDistribution(baseProvider, VAULT, {\n * [1]: ethProvider,\n * [42161]: arbProvider,\n * })\n * console.log(`Hub liquid: ${dist.hubLiquidBalance}`)\n * console.log(`Total actual: ${dist.totalActual}`)\n * ```\n */\nexport async function getVaultDistribution(\n hubProvider: Provider,\n vault: string,\n spokeProviders: Record<number, Provider>,\n): Promise<VaultDistribution> {\n // Read hub status\n const hubStatus = await getVaultStatus(hubProvider, vault);\n\n const hubChainId = Number((await hubProvider.getNetwork()).chainId);\n const hubTotalAssets = hubStatus.totalAssets;\n const hubLiquidBalance = hubStatus.hubLiquidBalance;\n const hubStrategyBalance =\n hubTotalAssets > hubLiquidBalance ? hubTotalAssets - hubLiquidBalance : 0n;\n\n // Read each spoke's totalAssets in parallel, never throwing\n const spokeEntries = Object.entries(spokeProviders).map(([chainIdStr, provider]) => ({\n chainId: Number(chainIdStr),\n provider,\n }));\n\n const spokeBalances: SpokeBalance[] = await Promise.all(\n spokeEntries.map(async ({ chainId, provider }): Promise<SpokeBalance> => {\n try {\n const spokeStatus = await getVaultStatus(provider, vault);\n return { chainId, totalAssets: spokeStatus.totalAssets, isReachable: true };\n } catch {\n return { chainId, totalAssets: 0n, isReachable: false };\n }\n }),\n );\n\n // totalActual = hub + reachable spokes\n const reachableSpokeSum = spokeBalances\n .filter((s) => s.isReachable)\n .reduce((acc, s) => acc + s.totalAssets, 0n);\n\n const totalActual = hubTotalAssets + reachableSpokeSum;\n\n return {\n hubChainId,\n hubLiquidBalance,\n hubStrategyBalance,\n hubTotalAssets,\n spokesDeployedBalance: hubStatus.spokesDeployedBalance,\n spokeBalances,\n totalActual,\n oracleAccountingEnabled: hubStatus.oracleAccountingEnabled,\n };\n}\n\n/**\n * Hub-only distribution — uses topology to discover spokes but does NOT\n * read spoke chains (no spoke providers needed).\n *\n * Returns hub data plus the list of spoke chainIds from the factory.\n * `spokeBalances` will be empty — callers must provide spoke providers to\n * `getVaultDistribution` for actual spoke reads.\n *\n * @param hubProvider Provider connected to the hub chain\n * @param vault Vault address\n *\n * @example\n * ```ts\n * const dist = await getVaultDistributionWithTopology(baseProvider, VAULT)\n * // dist.spokeBalances === [] (no spoke providers provided)\n * // dist.spokeChainIds tells you which chains to query\n * ```\n */\nexport async function getVaultDistributionWithTopology(\n hubProvider: Provider,\n vault: string,\n): Promise<VaultDistribution & { spokeChainIds: number[] }> {\n // Read hub status and topology in parallel\n const [hubStatus, topology] = await Promise.all([\n getVaultStatus(hubProvider, vault),\n getVaultTopology(hubProvider, vault),\n ]);\n\n const hubChainId = Number((await hubProvider.getNetwork()).chainId);\n const hubTotalAssets = hubStatus.totalAssets;\n const hubLiquidBalance = hubStatus.hubLiquidBalance;\n const hubStrategyBalance =\n hubTotalAssets > hubLiquidBalance ? hubTotalAssets - hubLiquidBalance : 0n;\n\n return {\n hubChainId,\n hubLiquidBalance,\n hubStrategyBalance,\n hubTotalAssets,\n spokesDeployedBalance: hubStatus.spokesDeployedBalance,\n spokeBalances: [],\n totalActual: hubTotalAssets, // hub-only, no spoke data\n oracleAccountingEnabled: hubStatus.oracleAccountingEnabled,\n spokeChainIds: topology.spokeChainIds,\n };\n}\n","/**\n * Spoke route helpers for the MoreVaults ethers.js v6 SDK.\n *\n * Provides functions to discover inbound/outbound cross-chain deposit and\n * redemption routes, and to quote LayerZero fees for those routes.\n */\n\nimport { Contract, ZeroAddress } from \"ethers\";\nimport type { Provider } from \"ethers\";\nimport { OFT_ROUTES, CHAIN_ID_TO_EID, createChainProvider } from \"./chains\";\nimport { OFT_ABI, ERC20_ABI } from \"./abis\";\nimport { isAsyncMode, quoteLzFee } from \"./utils\";\nimport { getVaultTopology } from \"./topology\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface OutboundRoute {\n /** Chain ID where user can receive shares/assets */\n chainId: number;\n /** Whether this chain is the hub (direct redeem) or a spoke (shares bridged back) */\n routeType: \"hub\" | \"spoke\";\n /** LZ EID for this chain */\n eid: number;\n /** Native gas symbol */\n nativeSymbol: string;\n}\n\nexport interface InboundRoute {\n /** Internal route identifier from OFT_ROUTES (e.g. 'stgUSDC') — do NOT show to users */\n symbol: string;\n /** Chain ID where user sends from */\n spokeChainId: number;\n /**\n * How the deposit is executed:\n * - 'direct' → user is on the hub chain, vault uses standard ERC-4626 (depositSimple). No LZ fee.\n * - 'direct-async' → user is on the hub chain, vault uses async accounting (depositAsync). LZ fee required.\n * - 'oft-compose' → user is on a spoke chain, use depositFromSpoke via OFT compose. LZ fee required.\n */\n depositType: \"direct\" | \"direct-async\" | \"oft-compose\";\n /** OFT contract on spoke chain — pass as `spokeOFT` to depositFromSpoke. Null for direct deposits. */\n spokeOft: string | null;\n /** Token user must approve on spoke chain (ZeroAddress = native ETH) */\n spokeToken: string;\n /**\n * Human-readable symbol of the token the user needs to hold on the spoke chain.\n * For OFTAdapters this is the underlying token symbol (e.g. 'USDC', 'weETH').\n * For pure OFTs this is the OFT's own symbol (e.g. 'sUSDe', 'USDe').\n * Use this — not `symbol` — when displaying the token name to users.\n */\n sourceTokenSymbol: string;\n /** OFT contract on hub chain — receives tokens for the composer. Null for direct deposits. */\n hubOft: string | null;\n /** oftCmd to use in SendParam (0x01 for Stargate taxi, 0x for standard OFT) */\n oftCmd: string;\n /** LZ fee estimate in native wei of the SPOKE chain (not always ETH — e.g. FLOW on Flow EVM) */\n lzFeeEstimate: bigint;\n /** Native gas token symbol for the spoke chain — use this when displaying the fee */\n nativeSymbol: string;\n}\n\nexport interface InboundRouteWithBalance extends InboundRoute {\n /** User's token balance on the spoke chain */\n userBalance: bigint;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Native gas token symbol per chain ID — lzFeeEstimate is denominated in this token */\nexport const NATIVE_SYMBOL: Partial<Record<number, string>> = {\n 1: \"ETH\",\n 10: \"ETH\",\n 42161: \"ETH\",\n 8453: \"ETH\",\n 747: \"FLOW\",\n 146: \"S\",\n 56: \"BNB\",\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst SYMBOL_ABI = [\n \"function symbol() view returns (string)\",\n] as const;\n\n/** Read ERC20 symbol() on-chain. Falls back to `fallbackSymbol` if the call fails. */\nasync function readTokenSymbol(\n provider: Provider | null,\n token: string,\n fallbackSymbol: string,\n): Promise<string> {\n if (!provider) return fallbackSymbol;\n try {\n const contract = new Contract(token, SYMBOL_ABI, provider);\n return await (contract.symbol() as Promise<string>);\n } catch {\n return fallbackSymbol;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Find all valid OFT inbound routes for a vault.\n *\n * Only returns routes for chains where the vault has a registered spoke —\n * this is required so the composer can send shares back to the user's chain.\n * The hub chain is always included as a 'direct' deposit option.\n *\n * Routes that revert on quoteSend() (no liquidity, no peer) are excluded.\n *\n * @param hubChainId Chain ID of the vault hub (e.g. 8453 for Base)\n * @param vault Vault address (to resolve registered spoke chains)\n * @param vaultAsset vault.asset() address on the hub chain\n * @param userAddress User address (used as receiver for fee quote)\n */\nexport async function getInboundRoutes(\n hubChainId: number,\n vault: string,\n vaultAsset: string,\n userAddress: string,\n): Promise<InboundRoute[]> {\n const hubEid = CHAIN_ID_TO_EID[hubChainId];\n if (!hubEid) throw new Error(`No LZ EID for hub chainId ${hubChainId}`);\n\n // Fetch vault topology to get registered spoke chains\n const hubProvider = createChainProvider(hubChainId);\n if (!hubProvider) throw new Error(`No public RPC for hub chainId ${hubChainId}`);\n const topology = await getVaultTopology(hubProvider, vault);\n const registeredSpokes = new Set(topology.spokeChainIds);\n\n const results: InboundRoute[] = [];\n\n const vaultAssetNorm = vaultAsset.toLowerCase();\n\n for (const [symbol, chainMap] of Object.entries(OFT_ROUTES)) {\n const hubEntry = (chainMap as Record<number, { oft: string; token: string }>)[hubChainId];\n if (!hubEntry) continue;\n\n // Does this OFT deliver the right asset to the hub?\n if (hubEntry.token.toLowerCase() !== vaultAssetNorm) continue;\n\n // oftCmd for OFT compose deposits: always '0x' (TAXI mode = immediate delivery with composeMsg).\n const oftCmd = \"0x\";\n\n // Only check chains where the vault has a registered spoke\n const spokesToCheck = Object.keys(chainMap)\n .map(Number)\n .filter((id) => id !== hubChainId && registeredSpokes.has(id));\n\n await Promise.allSettled(\n spokesToCheck.map(async (spokeChainId) => {\n const spokeEntry = (chainMap as Record<number, { oft: string; token: string }>)[spokeChainId];\n if (!spokeEntry) return;\n\n const spokeProvider = createChainProvider(spokeChainId);\n if (!spokeProvider) return;\n\n // Validate route via quoteSend — if it reverts, skip\n try {\n const receiverBytes32 =\n \"0x\" + userAddress.replace(/^0x/, \"\").toLowerCase().padStart(64, \"0\");\n\n const spokeOft = new Contract(spokeEntry.oft, OFT_ABI, spokeProvider);\n const [feeResult, sourceTokenSymbol] = await Promise.all([\n spokeOft.quoteSend(\n {\n dstEid: hubEid,\n to: receiverBytes32,\n amountLD: 1_000_000n,\n minAmountLD: 0n,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd,\n },\n false,\n ),\n readTokenSymbol(spokeProvider, spokeEntry.token, symbol),\n ]);\n\n results.push({\n symbol,\n spokeChainId,\n depositType: \"oft-compose\",\n spokeOft: spokeEntry.oft,\n spokeToken: spokeEntry.token,\n sourceTokenSymbol,\n hubOft: hubEntry.oft,\n oftCmd,\n lzFeeEstimate: feeResult.nativeFee as bigint,\n nativeSymbol: NATIVE_SYMBOL[spokeChainId] ?? \"ETH\",\n });\n } catch {\n // Route not available — skip silently\n }\n }),\n );\n }\n\n // Add the hub chain itself as a deposit option.\n // For async vaults the vault uses depositAsync which requires a LZ fee even on the hub chain.\n const [asyncMode, ...hubOftEntries] = await Promise.all([\n isAsyncMode(hubProvider, vault),\n ...Object.entries(OFT_ROUTES).map(async ([sym, chainMap]) => {\n const hubEntry = (chainMap as Record<number, { oft: string; token: string }>)[hubChainId];\n if (!hubEntry || hubEntry.token.toLowerCase() !== vaultAssetNorm) return null;\n return { symbol: sym, hubEntry };\n }),\n ]);\n\n const hubOftEntry = hubOftEntries.find((e) => e !== null) ?? null;\n\n if (hubOftEntry) {\n const { symbol, hubEntry } = hubOftEntry as { symbol: string; hubEntry: { oft: string; token: string } };\n const [sourceTokenSymbol, lzFeeEstimate] = await Promise.all([\n readTokenSymbol(hubProvider, hubEntry.token, symbol),\n asyncMode ? quoteLzFee(hubProvider, vault) : Promise.resolve(0n),\n ]);\n results.unshift({\n symbol,\n spokeChainId: hubChainId,\n depositType: asyncMode ? \"direct-async\" : \"direct\",\n spokeOft: null,\n spokeToken: hubEntry.token,\n sourceTokenSymbol,\n hubOft: null,\n oftCmd: \"0x\",\n lzFeeEstimate,\n nativeSymbol: NATIVE_SYMBOL[hubChainId] ?? \"ETH\",\n });\n }\n\n return results;\n}\n\n/**\n * Fetch user token balances for each inbound route in parallel.\n * Routes with native ETH as token (ZeroAddress) return the chain's ETH balance.\n *\n * @param routes Inbound routes from getInboundRoutes()\n * @param userAddress User wallet address\n */\nexport async function getUserBalancesForRoutes(\n routes: InboundRoute[],\n userAddress: string,\n): Promise<InboundRouteWithBalance[]> {\n return Promise.all(\n routes.map(async (route) => {\n const provider = createChainProvider(route.spokeChainId);\n if (!provider) return { ...route, userBalance: 0n };\n\n try {\n let userBalance: bigint;\n\n if (route.spokeToken.toLowerCase() === ZeroAddress.toLowerCase()) {\n userBalance = await provider.getBalance(userAddress);\n } else {\n const erc20 = new Contract(route.spokeToken, ERC20_ABI, provider);\n userBalance = await (erc20.balanceOf(userAddress) as Promise<bigint>);\n }\n\n return { ...route, userBalance };\n } catch {\n return { ...route, userBalance: 0n };\n }\n }),\n );\n}\n\n/**\n * Find all outbound routes for a vault — chains where a user can receive\n * shares/assets when redeeming.\n *\n * The hub chain is always first (direct redeem). Spoke chains follow\n * (shares are bridged back via the composer).\n *\n * @param hubChainId Chain ID of the vault hub (e.g. 8453 for Base)\n * @param vault Vault address (to resolve registered spoke chains)\n */\nexport async function getOutboundRoutes(\n hubChainId: number,\n vault: string,\n): Promise<OutboundRoute[]> {\n const hubEid = CHAIN_ID_TO_EID[hubChainId];\n if (!hubEid) throw new Error(`No LZ EID for hub chainId ${hubChainId}`);\n\n const hubProvider = createChainProvider(hubChainId);\n if (!hubProvider) throw new Error(`No public RPC for hub chainId ${hubChainId}`);\n\n const topology = await getVaultTopology(hubProvider, vault);\n\n const routes: OutboundRoute[] = [\n {\n chainId: hubChainId,\n routeType: \"hub\",\n eid: hubEid,\n nativeSymbol: NATIVE_SYMBOL[hubChainId] ?? \"ETH\",\n },\n ];\n\n for (const spokeChainId of topology.spokeChainIds) {\n const eid = CHAIN_ID_TO_EID[spokeChainId];\n if (!eid) continue;\n\n routes.push({\n chainId: spokeChainId,\n routeType: \"spoke\",\n eid,\n nativeSymbol: NATIVE_SYMBOL[spokeChainId] ?? \"ETH\",\n });\n }\n\n return routes;\n}\n\n/**\n * Quote the LayerZero native fee for a cross-chain deposit with a real amount.\n *\n * More precise than the `lzFeeEstimate` field on `InboundRoute`, which uses\n * a dummy 1 USDC amount.\n *\n * @param route An InboundRoute from `getInboundRoutes()`\n * @param hubChainId Chain ID of the vault hub (needed for LZ destination EID)\n * @param amount Real deposit amount in token decimals\n * @param userAddress User address (used as receiver for fee quote)\n * @returns Native fee in wei of the spoke chain's gas token, or 0n for direct deposits\n */\nexport async function quoteRouteDepositFee(\n route: InboundRoute,\n hubChainId: number,\n amount: bigint,\n userAddress: string,\n): Promise<bigint> {\n if (route.depositType === \"direct\") return 0n;\n\n const hubEid = CHAIN_ID_TO_EID[hubChainId];\n if (!hubEid) throw new Error(`No LZ EID for hub chainId ${hubChainId}`);\n\n if (!route.spokeOft) throw new Error(\"Route is oft-compose but spokeOft is null\");\n\n const spokeProvider = createChainProvider(route.spokeChainId);\n if (!spokeProvider) throw new Error(`No public RPC for spoke chainId ${route.spokeChainId}`);\n\n const receiverBytes32 =\n \"0x\" + userAddress.replace(/^0x/, \"\").toLowerCase().padStart(64, \"0\");\n\n const spokeOft = new Contract(route.spokeOft, OFT_ABI, spokeProvider);\n const feeResult = await spokeOft.quoteSend(\n {\n dstEid: hubEid,\n to: receiverBytes32,\n amountLD: amount,\n minAmountLD: 0n,\n extraOptions: \"0x\",\n composeMsg: \"0x\",\n oftCmd: route.oftCmd,\n },\n false,\n );\n\n return feeResult.nativeFee as bigint;\n}\n","import type { Signer } from 'ethers'\n\n/**\n * Cast an ethers Signer (e.g. from wagmi's useEthersSigner adapter) to\n * the SDK's expected type. Use this to avoid `as any` casts:\n * ```ts\n * import { useEthersSigner } from './wagmi-ethers-adapter'\n * import { asSdkSigner } from '@oydual31/more-vaults-sdk/ethers'\n * const signer = asSdkSigner(useEthersSigner())\n * ```\n * This function validates the signer is non-null and applies a documented\n * cast instead of an opaque `as any`.\n */\nexport function asSdkSigner(signer: unknown): Signer {\n if (!signer) throw new Error('[MoreVaults] No signer available. Make sure the wallet is connected and wagmi is configured correctly.')\n return signer as Signer\n}\n"]}