@oydual31/more-vaults-sdk 0.2.6 → 0.2.8

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
@@ -136,9 +136,14 @@ When you call `depositAsync`, `mintAsync`, or `redeemAsync`, the function return
136
136
  ```ts
137
137
  const { guid } = await depositAsync(...)
138
138
 
139
- // Poll status
139
+ // Option 1: Wait for finalization (recommended)
140
+ const final = await waitForAsyncRequest(publicClient, vault, guid)
141
+ // final.status: 'completed' | 'refunded'
142
+ // final.result: exact shares minted or assets received (bigint)
143
+
144
+ // Option 2: Check status once
140
145
  const info = await getAsyncRequestStatusLabel(publicClient, vault, guid)
141
- // info.status: 'pending' | 'ready-to-execute' | 'completed' | 'refunded'
146
+ // info.label: 'pending' | 'fulfilled' | 'finalized' | 'refunded'
142
147
  ```
143
148
 
144
149
  ---
@@ -179,7 +184,7 @@ The simplest way to use the SDK. `smartDeposit` and `smartRedeem` auto-detect th
179
184
  ### viem / wagmi
180
185
 
181
186
  ```ts
182
- import { smartDeposit, smartRedeem, getVaultStatus, LZ_TIMEOUTS } from '@oydual31/more-vaults-sdk/viem'
187
+ import { smartDeposit, smartRedeem, waitForAsyncRequest, getVaultStatus, LZ_TIMEOUTS } from '@oydual31/more-vaults-sdk/viem'
183
188
  import { createPublicClient, createWalletClient, http, parseUnits } from 'viem'
184
189
  import { base } from 'viem/chains'
185
190
 
@@ -200,7 +205,12 @@ const depositResult = await smartDeposit(
200
205
  if ('guid' in depositResult) {
201
206
  console.log('Async deposit — waiting for LZ callback (~5 min)')
202
207
  console.log('GUID:', depositResult.guid)
203
- // Poll for shares using LZ_TIMEOUTS.LZ_READ_CALLBACK as timeout
208
+
209
+ // Wait for finalization by GUID — returns exact shares minted
210
+ const final = await waitForAsyncRequest(publicClient, VAULT, depositResult.guid)
211
+ // final.status: 'completed' | 'refunded'
212
+ // final.result: shares minted (bigint)
213
+ console.log('Shares minted:', final.result)
204
214
  } else {
205
215
  console.log('Sync deposit — shares:', depositResult.shares)
206
216
  }
@@ -216,7 +226,9 @@ const redeemResult = await smartRedeem(
216
226
 
217
227
  if ('guid' in redeemResult) {
218
228
  console.log('Async redeem — waiting for LZ callback (~5 min)')
219
- // Poll for USDC balance increase
229
+
230
+ const final = await waitForAsyncRequest(publicClient, VAULT, redeemResult.guid)
231
+ console.log('Assets received:', final.result)
220
232
  } else {
221
233
  console.log('Sync redeem — assets:', redeemResult.assets)
222
234
  }
@@ -287,7 +299,8 @@ Step 3 (Hub): bridgeAssetsToSpoke() — assets hub->spoke via Stargate/OF
287
299
  |----------|-------------|
288
300
  | `waitForCompose` | Wait for pending compose in LZ Endpoint's composeQueue |
289
301
  | `quoteComposeFee` | Quote ETH needed for `executeCompose` (readFee + shareSendFee) |
290
- | `executeCompose` | Execute pending compose on hub chain |
302
+ | `executeCompose` | Execute pending compose on hub chain. Returns `{ txHash, guid? }` — GUID present for async vaults |
303
+ | `waitForAsyncRequest` | Poll async request by GUID until finalized. Returns `{ status, result }` with exact amounts |
291
304
 
292
305
  ### User helpers (read-only, no gas)
293
306
 
@@ -295,7 +308,8 @@ Full reference: [docs/user-helpers.md](./docs/user-helpers.md)
295
308
 
296
309
  | Function | What it returns |
297
310
  |----------|----------------|
298
- | `getUserPosition` | shares, asset value, share price, pending withdrawal |
311
+ | `getUserPosition` | shares, asset value, share price, pending withdrawal (single chain) |
312
+ | `getUserPositionMultiChain` | shares across hub + all spokes, total shares, estimated assets |
299
313
  | `previewDeposit` | estimated shares for a given asset amount |
300
314
  | `previewRedeem` | estimated assets for a given share amount |
301
315
  | `canDeposit` | `{ allowed, reason }` — paused / cap-full / ok |
@@ -321,7 +335,8 @@ Full reference: [docs/user-helpers.md](./docs/user-helpers.md)
321
335
 
322
336
  | Function | Description |
323
337
  |----------|-------------|
324
- | `getVaultTopology` | Hub/spoke chain IDs, OFT routes, composer addresses |
338
+ | `discoverVaultTopology` | Auto-discover hub/spoke topology across all chains (no wallet needed) |
339
+ | `getVaultTopology` | Hub/spoke chain IDs, OFT routes, composer addresses (requires correct chain client) |
325
340
  | `getFullVaultTopology` | Topology + all on-chain config |
326
341
  | `getVaultDistribution` | TVL breakdown across hub + all spokes |
327
342
  | `isOnHubChain` | Check if user is on the hub chain |
@@ -1775,6 +1775,7 @@ async function getUserPositionMultiChain(vault, user) {
1775
1775
  });
1776
1776
  const [withdrawShares, timelockEndsAt] = withdrawalRequest;
1777
1777
  const spokeShares = {};
1778
+ const rawSpokeShares = {};
1778
1779
  if (topo.spokeChainIds.length > 0) {
1779
1780
  let hubShareOft = null;
1780
1781
  try {
@@ -1797,7 +1798,7 @@ async function getUserPositionMultiChain(vault, user) {
1797
1798
  const spokePromises = topo.spokeChainIds.map(async (spokeChainId) => {
1798
1799
  try {
1799
1800
  const spokeEid = CHAIN_ID_TO_EID[spokeChainId];
1800
- if (!spokeEid) return { chainId: spokeChainId, balance: 0n };
1801
+ if (!spokeEid) return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };
1801
1802
  const spokeOftBytes32 = await hubClient.readContract({
1802
1803
  address: hubShareOft,
1803
1804
  abi: OFT_ABI,
@@ -1806,24 +1807,34 @@ async function getUserPositionMultiChain(vault, user) {
1806
1807
  });
1807
1808
  const spokeOft = viem.getAddress(`0x${spokeOftBytes32.slice(-40)}`);
1808
1809
  if (spokeOft === "0x0000000000000000000000000000000000000000") {
1809
- return { chainId: spokeChainId, balance: 0n };
1810
+ return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };
1810
1811
  }
1811
1812
  const spokeClient = createChainClient(spokeChainId);
1812
- if (!spokeClient) return { chainId: spokeChainId, balance: 0n };
1813
- const balance = await spokeClient.readContract({
1814
- address: spokeOft,
1815
- abi: ERC20_ABI,
1816
- functionName: "balanceOf",
1817
- args: [u]
1813
+ if (!spokeClient) return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };
1814
+ const [rawBalance, spokeOftDecimals] = await spokeClient.multicall({
1815
+ contracts: [
1816
+ { address: spokeOft, abi: ERC20_ABI, functionName: "balanceOf", args: [u] },
1817
+ { address: spokeOft, abi: METADATA_ABI, functionName: "decimals" }
1818
+ ],
1819
+ allowFailure: false
1818
1820
  });
1819
- return { chainId: spokeChainId, balance };
1821
+ let balance;
1822
+ if (spokeOftDecimals > decimals) {
1823
+ balance = rawBalance / 10n ** BigInt(spokeOftDecimals - decimals);
1824
+ } else if (spokeOftDecimals < decimals) {
1825
+ balance = rawBalance * 10n ** BigInt(decimals - spokeOftDecimals);
1826
+ } else {
1827
+ balance = rawBalance;
1828
+ }
1829
+ return { chainId: spokeChainId, balance, rawBalance };
1820
1830
  } catch {
1821
- return { chainId: spokeChainId, balance: 0n };
1831
+ return { chainId: spokeChainId, balance: 0n, rawBalance: 0n };
1822
1832
  }
1823
1833
  });
1824
1834
  const results = await Promise.all(spokePromises);
1825
- for (const { chainId, balance } of results) {
1835
+ for (const { chainId, balance, rawBalance } of results) {
1826
1836
  spokeShares[chainId] = balance;
1837
+ rawSpokeShares[chainId] = rawBalance;
1827
1838
  }
1828
1839
  }
1829
1840
  }
@@ -1843,6 +1854,7 @@ async function getUserPositionMultiChain(vault, user) {
1843
1854
  return {
1844
1855
  hubShares,
1845
1856
  spokeShares,
1857
+ rawSpokeShares,
1846
1858
  totalShares,
1847
1859
  estimatedAssets,
1848
1860
  sharePrice,