@oydual31/more-vaults-sdk 0.1.2 → 0.1.3
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/dist/react/index.cjs +1108 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +382 -0
- package/dist/react/index.d.ts +382 -0
- package/dist/react/index.js +1097 -0
- package/dist/react/index.js.map +1 -0
- package/dist/userHelpers-CZLB9oQ4.d.cts +286 -0
- package/dist/userHelpers-CZLB9oQ4.d.ts +286 -0
- package/dist/viem/index.d.cts +2 -284
- package/dist/viem/index.d.ts +2 -284
- package/package.json +26 -5
- package/src/react/index.ts +26 -0
- package/src/react/useAsyncRequestStatus.ts +36 -0
- package/src/react/useDepositSimple.ts +76 -0
- package/src/react/useLzFee.ts +27 -0
- package/src/react/useOmniDeposit.ts +97 -0
- package/src/react/useOmniRedeem.ts +96 -0
- package/src/react/useRedeemShares.ts +77 -0
- package/src/react/useSmartDeposit.ts +70 -0
- package/src/react/useUserPosition.ts +29 -0
- package/src/react/useVaultMetadata.ts +29 -0
- package/src/react/useVaultStatus.ts +34 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react'
|
|
2
|
+
import { usePublicClient, useWalletClient, useChainId } from 'wagmi'
|
|
3
|
+
import {
|
|
4
|
+
asSdkClient,
|
|
5
|
+
redeemAsync,
|
|
6
|
+
getVaultStatus,
|
|
7
|
+
} from '../viem/index.js'
|
|
8
|
+
import type { AsyncRequestStatusInfo } from '../viem/index.js'
|
|
9
|
+
import { useLzFee } from './useLzFee.js'
|
|
10
|
+
import { useAsyncRequestStatus } from './useAsyncRequestStatus.js'
|
|
11
|
+
|
|
12
|
+
interface UseOmniRedeemReturn {
|
|
13
|
+
/** Execute approve + redeemAsync. Handles everything internally. */
|
|
14
|
+
redeem: (sharesInWei: bigint, receiver: `0x${string}`, owner: `0x${string}`) => Promise<void>
|
|
15
|
+
isLoading: boolean
|
|
16
|
+
txHash: `0x${string}` | undefined
|
|
17
|
+
/** GUID for cross-chain tracking. Available after tx confirmation. */
|
|
18
|
+
guid: `0x${string}` | undefined
|
|
19
|
+
/** Cross-chain request status. undefined until a guid is available. */
|
|
20
|
+
requestStatus: AsyncRequestStatusInfo | undefined
|
|
21
|
+
/** true when the wallet is connected to the wrong chain */
|
|
22
|
+
wrongChain: boolean
|
|
23
|
+
error: Error | undefined
|
|
24
|
+
reset: () => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Complete hook for async redeems on hub vaults (R5 flow).
|
|
29
|
+
*
|
|
30
|
+
* Handles: fee quote, chain validation, share approve, redeemAsync, and GUID polling.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const { redeem, isLoading, guid, requestStatus, wrongChain } = useOmniRedeem('0xVAULT', 747)
|
|
34
|
+
*
|
|
35
|
+
* if (wrongChain) return <SwitchNetworkButton chainId={747} />
|
|
36
|
+
*
|
|
37
|
+
* await redeem(sharesInWei, userAddress, userAddress)
|
|
38
|
+
* // requestStatus.status goes: 'pending' → 'completed' | 'refunded'
|
|
39
|
+
*/
|
|
40
|
+
export function useOmniRedeem(
|
|
41
|
+
vault: `0x${string}` | undefined,
|
|
42
|
+
hubChainId: number,
|
|
43
|
+
): UseOmniRedeemReturn {
|
|
44
|
+
const { data: walletClient } = useWalletClient({ chainId: hubChainId })
|
|
45
|
+
const publicClient = usePublicClient({ chainId: hubChainId })
|
|
46
|
+
const currentChainId = useChainId()
|
|
47
|
+
|
|
48
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
49
|
+
const [txHash, setTxHash] = useState<`0x${string}` | undefined>()
|
|
50
|
+
const [guid, setGuid] = useState<`0x${string}` | undefined>()
|
|
51
|
+
const [error, setError] = useState<Error | undefined>()
|
|
52
|
+
|
|
53
|
+
const { feeWithBuffer } = useLzFee(vault, hubChainId)
|
|
54
|
+
const { data: requestStatus } = useAsyncRequestStatus(vault, guid, hubChainId)
|
|
55
|
+
|
|
56
|
+
const wrongChain = currentChainId !== hubChainId
|
|
57
|
+
|
|
58
|
+
const redeem = useCallback(
|
|
59
|
+
async (sharesInWei: bigint, receiver: `0x${string}`, owner: `0x${string}`) => {
|
|
60
|
+
if (!vault || !walletClient || !publicClient || !feeWithBuffer) return
|
|
61
|
+
setIsLoading(true)
|
|
62
|
+
setError(undefined)
|
|
63
|
+
try {
|
|
64
|
+
const pc = asSdkClient(publicClient)
|
|
65
|
+
const status = await getVaultStatus(pc, vault)
|
|
66
|
+
// walletClient from wagmi is structurally compatible with viem WalletClient
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
const result = await redeemAsync(
|
|
69
|
+
walletClient as any,
|
|
70
|
+
pc,
|
|
71
|
+
{ vault, escrow: status.escrow, hubChainId },
|
|
72
|
+
sharesInWei,
|
|
73
|
+
receiver,
|
|
74
|
+
owner,
|
|
75
|
+
feeWithBuffer,
|
|
76
|
+
)
|
|
77
|
+
setTxHash(result.txHash)
|
|
78
|
+
setGuid(result.guid)
|
|
79
|
+
} catch (err) {
|
|
80
|
+
setError(err instanceof Error ? err : new Error(String(err)))
|
|
81
|
+
} finally {
|
|
82
|
+
setIsLoading(false)
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
[vault, walletClient, publicClient, feeWithBuffer, hubChainId],
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const reset = useCallback(() => {
|
|
89
|
+
setTxHash(undefined)
|
|
90
|
+
setGuid(undefined)
|
|
91
|
+
setError(undefined)
|
|
92
|
+
setIsLoading(false)
|
|
93
|
+
}, [])
|
|
94
|
+
|
|
95
|
+
return { redeem, isLoading, txHash, guid, requestStatus, wrongChain, error, reset }
|
|
96
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react'
|
|
2
|
+
import { usePublicClient, useWalletClient } from 'wagmi'
|
|
3
|
+
import { asSdkClient, redeemShares } from '../viem/index.js'
|
|
4
|
+
import type { RedeemResult } from '../viem/index.js'
|
|
5
|
+
|
|
6
|
+
interface UseRedeemSharesReturn {
|
|
7
|
+
/** Execute redeemShares (R1 flow). */
|
|
8
|
+
redeem: (sharesInWei: bigint, receiver: `0x${string}`, owner: `0x${string}`) => Promise<void>
|
|
9
|
+
isLoading: boolean
|
|
10
|
+
txHash: `0x${string}` | undefined
|
|
11
|
+
/** Assets received. Available after tx confirmation. */
|
|
12
|
+
assets: bigint | undefined
|
|
13
|
+
error: Error | undefined
|
|
14
|
+
reset: () => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hook for standard ERC-4626 share redemption (R1 flow).
|
|
19
|
+
*
|
|
20
|
+
* Used for local and oracle-on cross-chain vaults.
|
|
21
|
+
* No LZ fee required — single transaction.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const { redeem, isLoading, txHash, assets } = useRedeemShares('0xVAULT', 747)
|
|
25
|
+
* await redeem(sharesInWei, userAddress, userAddress)
|
|
26
|
+
*/
|
|
27
|
+
export function useRedeemShares(
|
|
28
|
+
vault: `0x${string}` | undefined,
|
|
29
|
+
chainId: number,
|
|
30
|
+
): UseRedeemSharesReturn {
|
|
31
|
+
const { data: walletClient } = useWalletClient({ chainId })
|
|
32
|
+
const publicClient = usePublicClient({ chainId })
|
|
33
|
+
|
|
34
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
35
|
+
const [result, setResult] = useState<RedeemResult | undefined>()
|
|
36
|
+
const [error, setError] = useState<Error | undefined>()
|
|
37
|
+
|
|
38
|
+
const redeem = useCallback(
|
|
39
|
+
async (sharesInWei: bigint, receiver: `0x${string}`, owner: `0x${string}`) => {
|
|
40
|
+
if (!vault || !walletClient || !publicClient) return
|
|
41
|
+
setIsLoading(true)
|
|
42
|
+
setError(undefined)
|
|
43
|
+
try {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
const res = await redeemShares(
|
|
46
|
+
walletClient as any,
|
|
47
|
+
asSdkClient(publicClient),
|
|
48
|
+
{ vault, hubChainId: chainId },
|
|
49
|
+
sharesInWei,
|
|
50
|
+
receiver,
|
|
51
|
+
owner,
|
|
52
|
+
)
|
|
53
|
+
setResult(res)
|
|
54
|
+
} catch (err) {
|
|
55
|
+
setError(err instanceof Error ? err : new Error(String(err)))
|
|
56
|
+
} finally {
|
|
57
|
+
setIsLoading(false)
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[vault, walletClient, publicClient, chainId],
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const reset = useCallback(() => {
|
|
64
|
+
setResult(undefined)
|
|
65
|
+
setError(undefined)
|
|
66
|
+
setIsLoading(false)
|
|
67
|
+
}, [])
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
redeem,
|
|
71
|
+
isLoading,
|
|
72
|
+
txHash: result?.txHash,
|
|
73
|
+
assets: result?.assets,
|
|
74
|
+
error,
|
|
75
|
+
reset,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { DepositResult, AsyncRequestResult, AsyncRequestStatusInfo } from '../viem/index.js'
|
|
2
|
+
import { useVaultStatus } from './useVaultStatus.js'
|
|
3
|
+
import { useOmniDeposit } from './useOmniDeposit.js'
|
|
4
|
+
import { useDepositSimple } from './useDepositSimple.js'
|
|
5
|
+
|
|
6
|
+
interface UseSmartDepositReturn {
|
|
7
|
+
/**
|
|
8
|
+
* Execute deposit using the correct flow for this vault's mode.
|
|
9
|
+
* For async vaults: wraps depositAsync (D4) — returns guid for tracking.
|
|
10
|
+
* For local/oracle vaults: wraps depositSimple (D1/D3) — returns shares.
|
|
11
|
+
*/
|
|
12
|
+
deposit: (amountInWei: bigint, receiver: `0x${string}`) => Promise<void>
|
|
13
|
+
isLoading: boolean
|
|
14
|
+
txHash: `0x${string}` | undefined
|
|
15
|
+
/** Shares minted (available for D1/D3 vaults after confirmation, undefined for D4). */
|
|
16
|
+
shares: bigint | undefined
|
|
17
|
+
/** GUID for cross-chain tracking (D4 vaults only). */
|
|
18
|
+
guid: `0x${string}` | undefined
|
|
19
|
+
/** Cross-chain request status (D4 vaults only). */
|
|
20
|
+
requestStatus: AsyncRequestStatusInfo | undefined
|
|
21
|
+
/** true when the wallet is connected to the wrong chain (D4 vaults only). */
|
|
22
|
+
wrongChain: boolean
|
|
23
|
+
/** Vault mode loaded from getVaultStatus. undefined while loading. */
|
|
24
|
+
vaultMode: 'local' | 'cross-chain-oracle' | 'cross-chain-async' | 'paused' | 'full' | undefined
|
|
25
|
+
error: Error | undefined
|
|
26
|
+
reset: () => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Auto-selects the correct deposit flow based on vault mode.
|
|
31
|
+
* Best for frontends that support multiple vault types.
|
|
32
|
+
*
|
|
33
|
+
* Internally uses useVaultStatus to detect the mode, then delegates to:
|
|
34
|
+
* - useOmniDeposit (D4) for 'cross-chain-async' vaults
|
|
35
|
+
* - useDepositSimple (D1/D3) for 'local' and 'cross-chain-oracle' vaults
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* const { deposit, isLoading, guid, requestStatus, vaultMode } = useSmartDeposit('0xVAULT', 747)
|
|
39
|
+
*
|
|
40
|
+
* if (vaultMode === 'paused') return <PausedBadge />
|
|
41
|
+
*
|
|
42
|
+
* await deposit(parseUnits('100', 6), userAddress)
|
|
43
|
+
* // For async vaults: poll requestStatus until 'completed'
|
|
44
|
+
* // For sync vaults: txHash + shares are available immediately
|
|
45
|
+
*/
|
|
46
|
+
export function useSmartDeposit(
|
|
47
|
+
vault: `0x${string}` | undefined,
|
|
48
|
+
hubChainId: number,
|
|
49
|
+
): UseSmartDepositReturn {
|
|
50
|
+
const { data: status } = useVaultStatus(vault, hubChainId)
|
|
51
|
+
const omni = useOmniDeposit(vault, hubChainId)
|
|
52
|
+
const simple = useDepositSimple(vault, hubChainId)
|
|
53
|
+
|
|
54
|
+
const isAsync = status?.mode === 'cross-chain-async'
|
|
55
|
+
|
|
56
|
+
const deposit = isAsync ? omni.deposit : simple.deposit
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
deposit,
|
|
60
|
+
isLoading: isAsync ? omni.isLoading : simple.isLoading,
|
|
61
|
+
txHash: isAsync ? omni.txHash : simple.txHash,
|
|
62
|
+
shares: isAsync ? undefined : simple.shares,
|
|
63
|
+
guid: isAsync ? omni.guid : undefined,
|
|
64
|
+
requestStatus: isAsync ? omni.requestStatus : undefined,
|
|
65
|
+
wrongChain: isAsync ? omni.wrongChain : false,
|
|
66
|
+
vaultMode: status?.mode,
|
|
67
|
+
error: isAsync ? omni.error : simple.error,
|
|
68
|
+
reset: isAsync ? omni.reset : simple.reset,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query'
|
|
2
|
+
import { usePublicClient } from 'wagmi'
|
|
3
|
+
import { asSdkClient, getUserPosition } from '../viem/index.js'
|
|
4
|
+
import type { UserPosition } from '../viem/index.js'
|
|
5
|
+
|
|
6
|
+
export type { UserPosition }
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read the user's current position in a vault.
|
|
10
|
+
* Refetches every 15s to keep the balance display current.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const { data: position } = useUserPosition('0xVAULT', '0xUSER', 747)
|
|
14
|
+
* // position.shares, position.estimatedAssets, position.pendingWithdrawal
|
|
15
|
+
*/
|
|
16
|
+
export function useUserPosition(
|
|
17
|
+
vault: `0x${string}` | undefined,
|
|
18
|
+
user: `0x${string}` | undefined,
|
|
19
|
+
chainId: number,
|
|
20
|
+
) {
|
|
21
|
+
const publicClient = usePublicClient({ chainId })
|
|
22
|
+
return useQuery({
|
|
23
|
+
queryKey: ['userPosition', vault, user, chainId],
|
|
24
|
+
queryFn: () => getUserPosition(asSdkClient(publicClient), vault!, user!),
|
|
25
|
+
enabled: !!vault && !!user && !!publicClient,
|
|
26
|
+
refetchInterval: 15_000,
|
|
27
|
+
staleTime: 10_000,
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query'
|
|
2
|
+
import { usePublicClient } from 'wagmi'
|
|
3
|
+
import { asSdkClient, getVaultMetadata } from '../viem/index.js'
|
|
4
|
+
import type { VaultMetadata } from '../viem/index.js'
|
|
5
|
+
|
|
6
|
+
export type { VaultMetadata }
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read display metadata for a vault and its underlying token.
|
|
10
|
+
* Uses a long stale time (5 min) because metadata rarely changes.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const { data: meta } = useVaultMetadata('0xVAULT', 747)
|
|
14
|
+
* // meta.name, meta.symbol, meta.underlying, meta.underlyingSymbol
|
|
15
|
+
*/
|
|
16
|
+
export function useVaultMetadata(
|
|
17
|
+
vault: `0x${string}` | undefined,
|
|
18
|
+
chainId: number,
|
|
19
|
+
) {
|
|
20
|
+
const publicClient = usePublicClient({ chainId })
|
|
21
|
+
return useQuery({
|
|
22
|
+
queryKey: ['vaultMetadata', vault, chainId],
|
|
23
|
+
queryFn: () => getVaultMetadata(asSdkClient(publicClient), vault!),
|
|
24
|
+
enabled: !!vault && !!publicClient,
|
|
25
|
+
// Metadata (name, symbol, underlying) changes very rarely — 5 min stale time
|
|
26
|
+
staleTime: 5 * 60_000,
|
|
27
|
+
refetchInterval: 5 * 60_000,
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query'
|
|
2
|
+
import { usePublicClient } from 'wagmi'
|
|
3
|
+
import { asSdkClient, getVaultStatus } from '../viem/index.js'
|
|
4
|
+
import type { VaultStatus } from '../viem/index.js'
|
|
5
|
+
|
|
6
|
+
export type { VaultStatus }
|
|
7
|
+
|
|
8
|
+
interface UseVaultStatusOptions {
|
|
9
|
+
/** Refetch interval in ms. Default: 30_000 (30s) */
|
|
10
|
+
refetchInterval?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read the full vault status snapshot.
|
|
15
|
+
* Automatically refetches on a configurable interval.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const { data: status, isLoading } = useVaultStatus('0xVAULT', 747)
|
|
19
|
+
* if (status?.mode === 'cross-chain-async') { ... }
|
|
20
|
+
*/
|
|
21
|
+
export function useVaultStatus(
|
|
22
|
+
vault: `0x${string}` | undefined,
|
|
23
|
+
chainId: number,
|
|
24
|
+
options?: UseVaultStatusOptions,
|
|
25
|
+
) {
|
|
26
|
+
const publicClient = usePublicClient({ chainId })
|
|
27
|
+
return useQuery({
|
|
28
|
+
queryKey: ['vaultStatus', vault, chainId],
|
|
29
|
+
queryFn: () => getVaultStatus(asSdkClient(publicClient), vault!),
|
|
30
|
+
enabled: !!vault && !!publicClient,
|
|
31
|
+
refetchInterval: options?.refetchInterval ?? 30_000,
|
|
32
|
+
staleTime: 15_000,
|
|
33
|
+
})
|
|
34
|
+
}
|