@oydual31/more-vaults-sdk 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,10 +8,10 @@ npm install @oydual31/more-vaults-sdk
8
8
 
9
9
  ```ts
10
10
  // viem / wagmi
11
- import { getVaultStatus, smartDeposit, getUserBalances } from '@oydual31/more-vaults-sdk/viem'
11
+ import { smartDeposit, smartRedeem, getVaultStatus } from '@oydual31/more-vaults-sdk/viem'
12
12
 
13
13
  // ethers.js v6
14
- import { getVaultStatus, smartDeposit, getUserBalances } from '@oydual31/more-vaults-sdk/ethers'
14
+ import { getVaultStatus, depositSimple } from '@oydual31/more-vaults-sdk/ethers'
15
15
  ```
16
16
 
17
17
  ---
@@ -44,8 +44,8 @@ Redeem 100 shares → receive 105 USDC
44
44
 
45
45
  MoreVaults uses a **hub-and-spoke** model for cross-chain yield:
46
46
 
47
- - **Hub** (`isHub = true`): the chain where the vault does its accounting — mints/burns shares, accepts deposits and redemptions. All SDK flows target the hub. Flow EVM is the current reference deployment, but any EVM chain can be the hub.
48
- - **Spoke**: a position on another chain (Arbitrum, Base, etc.) where the vault has deployed funds for yield. Users on spoke chains bridge tokens to the hub via LayerZero OFT — they never interact with the spoke contracts directly.
47
+ - **Hub** (`isHub = true`): the chain where the vault does its accounting — mints/burns shares, accepts deposits and redemptions. All SDK flows target the hub.
48
+ - **Spoke**: a position on another chain (Arbitrum, Base, Ethereum, etc.) where the vault has deployed funds for yield. Users on spoke chains bridge tokens to the hub via LayerZero OFT.
49
49
 
50
50
  If a vault has `isHub = false`, it is a single-chain vault — no cross-chain flows apply, use D1/R1.
51
51
 
@@ -79,11 +79,6 @@ This means:
79
79
 
80
80
  **Repatriation** is the process of moving funds from spokes back to the hub so they become liquid again. This is a **manual, curator-only operation** (`executeBridging`). There is no automatic mechanism — the protocol does not pull funds from spokes on behalf of users.
81
81
 
82
- If a redeem fails because the hub is under-funded:
83
- 1. The user's shares are returned automatically (or the tx reverts before any state change for R1).
84
- 2. The vault curator must repatriate liquidity from the spokes.
85
- 3. The user retries the redeem once sufficient liquidity is available on the hub.
86
-
87
82
  ### Withdrawal queue and timelock
88
83
 
89
84
  Some vaults require shares to be "queued" before redemption:
@@ -107,9 +102,7 @@ const escrow = status.escrow // address(0) if not configured
107
102
 
108
103
  ### Same address on every chain (CREATE3)
109
104
 
110
- MoreVaults deploys all contracts using **CREATE3**, which means a vault has the **same address on every chain** where it exists. If the hub vault on Flow EVM is `0xABC...`, the corresponding escrow and spoke-side contracts are also at predictable, identical addresses across Arbitrum, Base, etc.
111
-
112
- This simplifies the frontend significantly — you don't need a separate address map per chain. One address identifies the vault everywhere.
105
+ MoreVaults deploys all contracts using **CREATE3**, which means a vault has the **same address on every chain** where it exists. If the hub vault on Base is `0xABC...`, the corresponding escrow and spoke-side contracts are also at predictable, identical addresses across Arbitrum, Ethereum, etc.
113
106
 
114
107
  ### VaultAddresses
115
108
 
@@ -118,13 +111,12 @@ Every flow function takes a `VaultAddresses` object:
118
111
  ```ts
119
112
  interface VaultAddresses {
120
113
  vault: Address // Vault address — same on every chain (CREATE3)
121
- escrow: Address // MoreVaultsEscrow — same address as vault on each chain, required for D4, D5, R5
122
- shareOFT?: Address // OFTAdapter for vault shares — required for R6 (spoke redeem)
123
- usdcOFT?: Address // OFT for the underlying token on the spoke — required for D6/D7
114
+ escrow?: Address // MoreVaultsEscrow — required for D4, D5, R5 (auto-resolved if omitted)
115
+ hubChainId?: number // Optional chain validation
124
116
  }
125
117
  ```
126
118
 
127
- For simple hub flows (D1, R1) you only need `vault`. For async flows you also need `escrow` — get it from `getVaultStatus(publicClient, vault).escrow`. For cross-chain flows from a spoke you also need the OFT addresses for that specific spoke chain.
119
+ For simple hub flows (D1, R1) you only need `vault`. For async flows the SDK auto-resolves the escrow from the vault if not provided.
128
120
 
129
121
  ### LayerZero EID
130
122
 
@@ -132,10 +124,10 @@ LayerZero identifies chains by an **Endpoint ID (EID)** — different from the c
132
124
 
133
125
  | Chain | Chain ID | LayerZero EID |
134
126
  |-------|----------|---------------|
135
- | Flow EVM | 747 | 30332 |
127
+ | Ethereum | 1 | 30101 |
136
128
  | Arbitrum | 42161 | 30110 |
137
129
  | Base | 8453 | 30184 |
138
- | Ethereum | 1 | 30101 |
130
+ | Flow EVM | 747 | 30332 |
139
131
 
140
132
  ### GUID (async request ID)
141
133
 
@@ -147,7 +139,6 @@ const { guid } = await depositAsync(...)
147
139
  // Poll status
148
140
  const info = await getAsyncRequestStatusLabel(publicClient, vault, guid)
149
141
  // info.status: 'pending' | 'ready-to-execute' | 'completed' | 'refunded'
150
- // info.result: shares minted or assets received once completed
151
142
  ```
152
143
 
153
144
  ---
@@ -177,88 +168,126 @@ const { data: walletClient } = useWalletClient()
177
168
  | `new BrowserProvider(window.ethereum).getSigner()` | Browser — MetaMask or any injected wallet |
178
169
  | `new Wallet(PRIVATE_KEY, new JsonRpcProvider(RPC_URL))` | Node.js — scripts, bots, backends |
179
170
 
180
- Read-only helpers (`getUserPosition`, `previewDeposit`, etc.) accept a bare `Provider` in the ethers version — no signer needed.
181
-
182
171
  > The client's chain must match the chain where the vault lives. Hub flows → the hub chain. Spoke deposit/redeem (D6/D7/R6) → the spoke chain.
183
172
 
184
173
  ---
185
174
 
186
- ## Quick start
175
+ ## Quick start — Smart flows (recommended)
176
+
177
+ The simplest way to use the SDK. `smartDeposit` and `smartRedeem` auto-detect the vault type and use the correct flow.
187
178
 
188
179
  ### viem / wagmi
189
180
 
190
181
  ```ts
191
- import { getVaultStatus, depositSimple, getUserPosition } from '@oydual31/more-vaults-sdk/viem'
182
+ import { smartDeposit, smartRedeem, getVaultStatus, LZ_TIMEOUTS } from '@oydual31/more-vaults-sdk/viem'
192
183
  import { createPublicClient, createWalletClient, http, parseUnits } from 'viem'
184
+ import { base } from 'viem/chains'
193
185
 
194
- const publicClient = createPublicClient({ chain: flowEvm, transport: http(RPC_URL) })
195
- const walletClient = createWalletClient({ account, chain: flowEvm, transport: http(RPC_URL) })
196
-
197
- // 1. Check vault status to know which flow to use
198
- const status = await getVaultStatus(publicClient, VAULT_ADDRESS)
199
- // status.mode → 'local' | 'cross-chain-oracle' | 'cross-chain-async' | 'paused' | 'full'
200
- // status.recommendedDepositFlow → 'depositSimple' | 'depositAsync' | 'none'
201
- // status.escrow → escrow address (needed for async flows)
186
+ const publicClient = createPublicClient({ chain: base, transport: http(RPC_URL) })
187
+ const walletClient = createWalletClient({ account, chain: base, transport: http(RPC_URL) })
202
188
 
203
- const addresses = { vault: VAULT_ADDRESS, escrow: status.escrow }
189
+ const VAULT = '0x8f740aba022b3fcc934ab75c581c04b75e72aba6'
204
190
 
205
- // 2. Deposit
206
- const { txHash, shares } = await depositSimple(
207
- walletClient, publicClient, addresses,
191
+ // --- Deposit ---
192
+ const depositResult = await smartDeposit(
193
+ walletClient, publicClient,
194
+ { vault: VAULT },
208
195
  parseUnits('100', 6), // 100 USDC
209
196
  account.address,
210
197
  )
211
198
 
212
- // 3. Read position
213
- const position = await getUserPosition(publicClient, VAULT_ADDRESS, account.address)
214
- console.log('Shares:', position.shares)
215
- console.log('Value:', position.estimatedAssets)
216
- ```
217
-
218
- ### ethers.js
219
-
220
- ```ts
221
- import { getVaultStatus, depositSimple, getUserPosition } from '@oydual31/more-vaults-sdk/ethers'
222
- import { BrowserProvider, parseUnits } from 'ethers'
223
-
224
- const provider = new BrowserProvider(window.ethereum)
225
- const signer = await provider.getSigner()
226
-
227
- const status = await getVaultStatus(provider, VAULT_ADDRESS)
228
- const addresses = { vault: VAULT_ADDRESS, escrow: status.escrow }
199
+ // Check if async (LZ Read callback needed)
200
+ if ('guid' in depositResult) {
201
+ console.log('Async deposit — waiting for LZ callback (~5 min)')
202
+ console.log('GUID:', depositResult.guid)
203
+ // Poll for shares using LZ_TIMEOUTS.LZ_READ_CALLBACK as timeout
204
+ } else {
205
+ console.log('Sync deposit — shares:', depositResult.shares)
206
+ }
229
207
 
230
- const { txHash, shares } = await depositSimple(
231
- signer, addresses,
232
- parseUnits('100', 6),
233
- await signer.getAddress(),
208
+ // --- Redeem ---
209
+ const redeemResult = await smartRedeem(
210
+ walletClient, publicClient,
211
+ { vault: VAULT },
212
+ shares,
213
+ account.address,
214
+ account.address,
234
215
  )
216
+
217
+ if ('guid' in redeemResult) {
218
+ console.log('Async redeem — waiting for LZ callback (~5 min)')
219
+ // Poll for USDC balance increase
220
+ } else {
221
+ console.log('Sync redeem — assets:', redeemResult.assets)
222
+ }
235
223
  ```
236
224
 
237
225
  ---
238
226
 
239
227
  ## Flows
240
228
 
241
- ### Deposit
229
+ ### Smart flows (auto-detection)
230
+
231
+ | Function | Description |
232
+ |----------|-------------|
233
+ | `smartDeposit` | Auto-detects vault mode → `depositSimple` (sync) or `depositAsync` (async) |
234
+ | `smartRedeem` | Auto-detects vault mode → `redeemShares` (sync) or `redeemAsync` (async) |
235
+
236
+ ### Hub-chain deposit
242
237
 
243
238
  | ID | Function | When to use | Doc |
244
239
  |----|----------|-------------|-----|
245
- | D1 | `depositSimple` | User on hub chain, oracle ON or local vault | [→](./docs/flows/D1-deposit-simple.md) |
246
- | D2 | `depositMultiAsset` | Deposit multiple tokens in one call | [](./docs/flows/D2-deposit-multi-asset.md) |
247
- | D3 | `depositCrossChainOracleOn` | Alias for D1 hub with oracle ON, explicit naming | [](./docs/flows/D3-deposit-oracle-on.md) |
248
- | D4 | `depositAsync` | Hub with oracle OFF async LZ Read, shares arrive in ~1–5 min | [](./docs/flows/D4-deposit-async.md) |
249
- | D5 | `mintAsync` | Same as D4 but user specifies exact share amount | [](./docs/flows/D5-mint-async.md) |
250
- | D6/D7 | `depositFromSpoke` | User on another chain tokens bridge via LZ OFT | [](./docs/flows/D6-D7-deposit-from-spoke.md) |
240
+ | | `smartDeposit` | **Recommended.** Auto-detects vault type. | |
241
+ | D1 | `depositSimple` | User on hub chain, oracle ON or local vault | [->](./docs/flows/D1-deposit-simple.md) |
242
+ | D2 | `depositMultiAsset` | Deposit multiple tokens in one call | [->](./docs/flows/D2-deposit-multi-asset.md) |
243
+ | D3 | `depositCrossChainOracleOn` | Alias for D1hub with oracle ON | [->](./docs/flows/D3-deposit-oracle-on.md) |
244
+ | D4 | `depositAsync` | Hub with oracle OFF async LZ Read | [->](./docs/flows/D4-deposit-async.md) |
245
+ | D5 | `mintAsync` | Same as D4 but user specifies exact share amount | [->](./docs/flows/D5-mint-async.md) |
246
+
247
+ ### Cross-chain deposit (spoke -> hub)
248
+
249
+ | ID | Function | When to use | Doc |
250
+ |----|----------|-------------|-----|
251
+ | D6/D7 | `depositFromSpoke` | User on spoke chain — tokens bridge via LZ OFT | [->](./docs/flows/D6-D7-deposit-from-spoke.md) |
252
+
253
+ For Stargate OFTs (stgUSDC, USDT, WETH), `depositFromSpoke` returns `composeData` — the user must execute a 2nd TX on the hub via `waitForCompose` + `executeCompose`. For standard OFTs, compose auto-executes in 1 TX.
251
254
 
252
- ### Redeem
255
+ ### Hub-chain redeem
253
256
 
254
257
  | ID | Function | When to use | Doc |
255
258
  |----|----------|-------------|-----|
256
- | R1 | `redeemShares` | Standard redeem, hub chain, no queue | [→](./docs/flows/R1-redeem-shares.md) |
257
- | R2 | `withdrawAssets` | Specify exact asset amount to receive | [](./docs/flows/R2-withdraw-assets.md) |
258
- | R3 | `requestRedeem` | Withdrawal queue enabled, no timelock | [](./docs/flows/R3-R4-request-redeem.md) |
259
- | R4 | `requestRedeem` | Withdrawal queue + mandatory wait period | [](./docs/flows/R3-R4-request-redeem.md) |
260
- | R5 | `redeemAsync` | Hub with oracle OFF async LZ Read | [](./docs/flows/R5-redeem-async.md) |
261
- | R6 | `bridgeSharesToHub` | User on spokestep 1: bridge shares to hub | [](./docs/flows/R6-bridge-shares-to-hub.md) |
259
+ | | `smartRedeem` | **Recommended.** Auto-detects vault type. | |
260
+ | R1 | `redeemShares` | Standard redeem, hub chain, no queue | [->](./docs/flows/R1-redeem-shares.md) |
261
+ | R2 | `withdrawAssets` | Specify exact asset amount to receive | [->](./docs/flows/R2-withdraw-assets.md) |
262
+ | R3 | `requestRedeem` | Withdrawal queue enabled, no timelock | [->](./docs/flows/R3-R4-request-redeem.md) |
263
+ | R4 | `requestRedeem` | Withdrawal queue + mandatory wait period | [->](./docs/flows/R3-R4-request-redeem.md) |
264
+ | R5 | `redeemAsync` | Hub with oracle OFF async LZ Read | [->](./docs/flows/R5-redeem-async.md) |
265
+
266
+ ### Cross-chain redeem (spoke -> hub -> spoke)
267
+
268
+ Full spoke redeem is a 3-step flow across two chains:
269
+
270
+ ```
271
+ Step 1 (Spoke): bridgeSharesToHub() — shares spoke->hub via SHARE_OFT (~7 min)
272
+ Step 2 (Hub): smartRedeem() — redeem on hub (auto-detects async, ~5 min callback)
273
+ Step 3 (Hub): bridgeAssetsToSpoke() — assets hub->spoke via Stargate/OFT (~13 min)
274
+ ```
275
+
276
+ | Function | Step | Doc |
277
+ |----------|------|-----|
278
+ | `resolveRedeemAddresses` | Pre-step: discover all addresses dynamically | — |
279
+ | `preflightSpokeRedeem` | Pre-step: validate balances + gas on both chains | — |
280
+ | `bridgeSharesToHub` | Step 1: bridge shares spoke->hub | [->](./docs/flows/R6-bridge-shares-to-hub.md) |
281
+ | `smartRedeem` | Step 2: redeem on hub | — |
282
+ | `bridgeAssetsToSpoke` | Step 3: bridge assets hub->spoke | [->](./docs/flows/R7-bridge-assets-to-spoke.md) |
283
+
284
+ ### Compose helpers (Stargate 2-TX flow)
285
+
286
+ | Function | Description |
287
+ |----------|-------------|
288
+ | `waitForCompose` | Wait for pending compose in LZ Endpoint's composeQueue |
289
+ | `quoteComposeFee` | Quote ETH needed for `executeCompose` (readFee + shareSendFee) |
290
+ | `executeCompose` | Execute pending compose on hub chain |
262
291
 
263
292
  ### User helpers (read-only, no gas)
264
293
 
@@ -274,6 +303,64 @@ Full reference: [docs/user-helpers.md](./docs/user-helpers.md)
274
303
  | `getVaultStatus` | full config snapshot + recommended flow + issues list |
275
304
  | `quoteLzFee` | native fee required for D4, D5, R5 |
276
305
  | `getAsyncRequestStatusLabel` | pending / ready-to-execute / completed / refunded |
306
+ | `getUserBalances` | shares + underlying balance in one call |
307
+ | `getMaxWithdrawable` | max assets redeemable given hub liquidity |
308
+ | `getVaultSummary` | metadata + status + user position combined |
309
+
310
+ ### Spoke route discovery
311
+
312
+ | Function | Description |
313
+ |----------|-------------|
314
+ | `getInboundRoutes` | All routes a user can deposit from (which chains/tokens) |
315
+ | `getUserBalancesForRoutes` | User balances for all inbound routes |
316
+ | `getOutboundRoutes` | All routes for spoke redeem (which chains to bridge back to) |
317
+ | `quoteRouteDepositFee` | LZ fee for a specific inbound route |
318
+ | `resolveRedeemAddresses` | Discover SHARE_OFT, asset OFT, spoke asset for a redeem route |
319
+
320
+ ### Topology & distribution
321
+
322
+ | Function | Description |
323
+ |----------|-------------|
324
+ | `getVaultTopology` | Hub/spoke chain IDs, OFT routes, composer addresses |
325
+ | `getFullVaultTopology` | Topology + all on-chain config |
326
+ | `getVaultDistribution` | TVL breakdown across hub + all spokes |
327
+ | `isOnHubChain` | Check if user is on the hub chain |
328
+
329
+ ---
330
+
331
+ ## LZ Timeouts (for UI integration)
332
+
333
+ ```ts
334
+ import { LZ_TIMEOUTS } from '@oydual31/more-vaults-sdk/viem'
335
+
336
+ LZ_TIMEOUTS.POLL_INTERVAL // 30s — interval between balance polls
337
+ LZ_TIMEOUTS.OFT_BRIDGE // 15 min — standard OFT bridge (shares or assets)
338
+ LZ_TIMEOUTS.STARGATE_BRIDGE // 30 min — Stargate bridge (slower, pool mechanics)
339
+ LZ_TIMEOUTS.LZ_READ_CALLBACK // 15 min — async deposit/redeem LZ Read callback
340
+ LZ_TIMEOUTS.COMPOSE_DELIVERY // 45 min — compose delivery to hub (spoke deposit)
341
+ LZ_TIMEOUTS.FULL_SPOKE_REDEEM // 60 min — full spoke->hub->spoke redeem
342
+ ```
343
+
344
+ Use these as timeout values in UI progress indicators. Do NOT timeout before these values — cross-chain operations can legitimately take this long.
345
+
346
+ ---
347
+
348
+ ## Pre-flight validation
349
+
350
+ Run pre-flight checks before submitting transactions to catch issues early:
351
+
352
+ ```ts
353
+ import { preflightSpokeDeposit, preflightSpokeRedeem } from '@oydual31/more-vaults-sdk/viem'
354
+
355
+ // Before spoke deposit
356
+ const check = await preflightSpokeDeposit(...)
357
+ // Validates: spoke balance, gas, hub composer setup
358
+
359
+ // Before spoke redeem
360
+ const check = await preflightSpokeRedeem(route, shares, userAddress, shareBridgeFee)
361
+ // Validates: shares on spoke, spoke gas (LZ fee + buffer), hub gas (asset bridge fee)
362
+ // Returns: estimatedAssetBridgeFee, hubLiquidBalance, etc.
363
+ ```
277
364
 
278
365
  ---
279
366
 
@@ -282,14 +369,15 @@ Full reference: [docs/user-helpers.md](./docs/user-helpers.md)
282
369
  ```
283
370
  more-vaults-sdk/
284
371
  ├── src/
285
- │ ├── viem/ viem/wagmi SDK
286
- └── ethers/ ethers.js v6 SDK
372
+ │ ├── viem/ <- viem/wagmi SDK
373
+ ├── ethers/ <- ethers.js v6 SDK
374
+ │ └── react/ <- React hooks (wagmi)
287
375
  ├── docs/
288
- │ ├── flows/ one .md per flow with detailed examples
376
+ │ ├── flows/ <- one .md per flow with detailed examples
289
377
  │ ├── user-helpers.md
290
378
  │ └── testing.md
291
- ├── tests/ integration tests (require Foundry + Anvil)
292
- └── contracts/ protocol Solidity source + mocks (for running tests)
379
+ ├── scripts/ <- E2E test scripts (mainnet)
380
+ └── tests/ <- integration tests (require Foundry + Anvil)
293
381
  ```
294
382
 
295
383
  Integration tests: [docs/testing.md](./docs/testing.md) — `bash tests/run.sh` runs all 43 tests.
@@ -31,6 +31,25 @@ var CHAIN_ID_TO_EID = {
31
31
  [CHAIN_IDS.base]: LZ_EIDS.base,
32
32
  [CHAIN_IDS.ethereum]: LZ_EIDS.ethereum
33
33
  };
34
+ var LZ_TIMEOUTS = {
35
+ /** Poll interval between balance/event checks */
36
+ POLL_INTERVAL: 3e4,
37
+ /** Standard OFT bridge (shares or assets, non-Stargate) */
38
+ OFT_BRIDGE: 9e5,
39
+ // 15 min
40
+ /** Stargate bridge (USDC, USDT, WETH) — slower due to pool mechanics */
41
+ STARGATE_BRIDGE: 18e5,
42
+ // 30 min
43
+ /** LZ Read callback (async vault actions) */
44
+ LZ_READ_CALLBACK: 9e5,
45
+ // 15 min
46
+ /** Compose delivery to hub (deposit from spoke) */
47
+ COMPOSE_DELIVERY: 27e5,
48
+ // 45 min
49
+ /** Full spoke→hub→spoke redeem (all steps combined) */
50
+ FULL_SPOKE_REDEEM: 36e5
51
+ // 60 min
52
+ };
34
53
 
35
54
  // src/ethers/types.ts
36
55
  var ActionType = {
@@ -827,6 +846,46 @@ async function bridgeSharesToHub(signer, shareOFT, hubChainEid, shares, receiver
827
846
  const receipt = await tx.wait();
828
847
  return { receipt };
829
848
  }
849
+ async function smartRedeem(signer, addresses, shares, receiver, owner, extraOptions = "0x") {
850
+ const provider = signer.provider;
851
+ const vault = addresses.vault;
852
+ const status = await getVaultStatus(provider, vault);
853
+ if (status.mode === "paused") {
854
+ throw new Error(`[MoreVaults] Vault ${vault} is paused. Cannot redeem.`);
855
+ }
856
+ if (status.recommendedDepositFlow === "depositAsync") {
857
+ const lzFee = await quoteLzFee(provider, vault, extraOptions);
858
+ return redeemAsync(signer, addresses, shares, receiver, owner, lzFee, extraOptions);
859
+ }
860
+ return redeemShares(signer, addresses, shares, receiver, owner);
861
+ }
862
+ async function bridgeAssetsToSpoke(signer, assetOFT, spokeChainEid, amount, receiver, lzFee, isStargate = true) {
863
+ const oft = new ethers.Contract(assetOFT, OFT_ABI, signer);
864
+ const token = await oft.token();
865
+ if (token.toLowerCase() !== assetOFT.toLowerCase()) {
866
+ await ensureAllowance4(signer, token, assetOFT, amount);
867
+ } else {
868
+ await ensureAllowance4(signer, assetOFT, assetOFT, amount);
869
+ }
870
+ const refundAddress = await signer.getAddress();
871
+ const toBytes32 = ethers.zeroPadValue(receiver, 32);
872
+ const sendParam = {
873
+ dstEid: spokeChainEid,
874
+ to: toBytes32,
875
+ amountLD: amount,
876
+ minAmountLD: amount * 99n / 100n,
877
+ // 1% slippage for Stargate
878
+ extraOptions: "0x",
879
+ composeMsg: "0x",
880
+ oftCmd: isStargate ? "0x01" : "0x"
881
+ };
882
+ const msgFee = { nativeFee: lzFee, lzTokenFee: 0n };
883
+ const tx = await oft.send(sendParam, msgFee, refundAddress, {
884
+ value: lzFee
885
+ });
886
+ const receipt = await tx.wait();
887
+ return { receipt };
888
+ }
830
889
  var MULTICALL3_ADDRESS2 = "0xcA11bde05977b3631167028862bE2a173976CA11";
831
890
  var MULTICALL3_ABI2 = [
832
891
  "function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)"
@@ -1057,6 +1116,7 @@ exports.EscrowNotConfiguredError = EscrowNotConfiguredError;
1057
1116
  exports.InsufficientLiquidityError = InsufficientLiquidityError;
1058
1117
  exports.LZ_EIDS = LZ_EIDS;
1059
1118
  exports.LZ_ENDPOINT_ABI = LZ_ENDPOINT_ABI;
1119
+ exports.LZ_TIMEOUTS = LZ_TIMEOUTS;
1060
1120
  exports.METADATA_ABI = METADATA_ABI;
1061
1121
  exports.MissingEscrowAddressError = MissingEscrowAddressError;
1062
1122
  exports.MoreVaultsError = MoreVaultsError;
@@ -1067,6 +1127,7 @@ exports.VAULT_ABI = VAULT_ABI;
1067
1127
  exports.VaultPausedError = VaultPausedError;
1068
1128
  exports.WrongChainError = WrongChainError;
1069
1129
  exports.asSdkSigner = asSdkSigner;
1130
+ exports.bridgeAssetsToSpoke = bridgeAssetsToSpoke;
1070
1131
  exports.bridgeSharesToHub = bridgeSharesToHub;
1071
1132
  exports.canDeposit = canDeposit;
1072
1133
  exports.depositAsync = depositAsync;
@@ -1100,6 +1161,7 @@ exports.redeemAsync = redeemAsync;
1100
1161
  exports.redeemShares = redeemShares;
1101
1162
  exports.requestRedeem = requestRedeem;
1102
1163
  exports.smartDeposit = smartDeposit;
1164
+ exports.smartRedeem = smartRedeem;
1103
1165
  exports.withdrawAssets = withdrawAssets;
1104
1166
  //# sourceMappingURL=index.cjs.map
1105
1167
  //# sourceMappingURL=index.cjs.map